wangEditor富文字編輯器+react+antd的使用(轉)
1、github上發現富文字編輯器:
2、結合react+antd的具體使用:
案例使用場景:MyModal為彈窗,彈窗顯示 編輯名稱及描述。描述使用wangeditor富文字編輯器實現。
MyModal.js
import { Form, Modal, Input, Row, Col } from 'antd';
import Editor from 'wangeditor';
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 3 }
},
wrapperCol : {
xs: { span: 24 },
sm: { span: 20 }
}
};
const FormItem = Form.Item;
@Form.create()
classMyModalextendsReact.Component {
constructor(props) {
super(props);
this.state = {
editorHtml: '',
editorText: '',
}
}
submit = values => {
this.props.form.validateFields((err, values) => {
if (!err) {
//提交表單處理事項
this.props.OnSubmit(values);
}
});
};
componentDidMount() {
//判斷modal是否需要顯示
if(this.props.visible) {
//獲取真實dom,創新富文字編輯器
vareditor = newEditor(ReactDOM.findDOMNode(this._div));
// 使用 onchange 函式監聽內容的變化,並實時更新到 state 中
editor .customConfig.onchange = (html) => {
this.setState({
editorHtml: html,
editorText: editor.txt.text()
})
//將html值設為form表單的desc屬性值
this.props.form.setFieldsValue({
'desc': html
});
}
editor.create();
}
}
//自定義表單驗證規則
validateEditorFrom = (rule, value, callback) => {
//此處根據富文字框的text值進行驗證,但注意富文字框中輸入空格,使用‘ ‘表示,此方法不能處理只輸入空格的驗證。
if (this.state.editorText.trim() === '') {
callback('不能為空');
}
// Note: 必須總是返回一個 callback,否則 validateFieldsAndScroll 無法響應
callback();
}
render() {
const { id, visible, confirmLoading } = this.props;
const { getFieldDecorator } = this.props.form;
getFieldDecorator('id', { initialValue: id });
return (
<Modal
title="編輯資訊"
width={'60%'}
confirmLoading={confirmLoading}
visible={visible}
onOk={this.submit}
onCancel={this.props.onCancel}
>
<Form>
<Row>
<Col>
<FormItem {...formItemLayout} label="名稱">
{getFieldDecorator('name', {
rules: [{ required: true, message: '請填寫名稱' }],
initialValue: ''
})(<Input />)}
</FormItem>
<FormItem {...formItemLayout} label="描述">
{getFieldDecorator('desc', {
rules: [{
required: true,
message: '請填寫描述',
}, {// 使用自定義的校驗規則
validator: this.validateEditorFrom
}],
initialValue: ''
})(<div ref={(ref) => this._div = ref}></div>)}
</FormItem>
</Col>
</Row>
</Form>
</Modal>
);
}
}
exportdefaultMyModal;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
index.js 點選連結呼叫彈窗:
mySubmit = (values)=>{
//value為form表單的物件
//處理提交邏輯
}
hideMyModal =()=>{
this.setState({
myModalVisible: false
})
}
render(){
return (
<MyModal
visible={myModalVisible}
confirmLoading={confirmLoading}
key={myModalVisible + 'edit'}
taskId={taskId}
onSubmit={this.mySubmit}
onCancel={this.hideMyModal}
/>
);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
需要設定富文字編輯的內容時,可以在react的componentDidMount生命週期函式中 使用editor.txt.html('<p>哈哈</p>')
進行設定。
const value = this.props.data && this.props.data.desc || '';
editor.txt.html(value);
- 1
- 2
3、知識點總結
(1) FormItem必填驗證,是怎麼關聯的?
<FormItem {...formItemLayout} label="名稱">
{getFieldDecorator('name', {
rules: [{ required: true, message: '請填寫名稱' }],
initialValue: ''
})(<Input />)}
</FormItem>
- 1
- 2
- 3
- 4
- 5
- 6
答案可以使用官網的話:
經過 getFieldDecorator 包裝的控制元件,表單控制元件會自動新增 value(或 valuePropName 指定的其他屬性) onChange(或 trigger 指定的其他屬性),資料同步將被 Form 接管,這會導致以下結果:
你不再需要也不應該用 onChange 來做同步,但還是可以繼續監聽 onChange 等事件。
你不能用控制元件的 value defaultValue 等屬性來設定表單域的值,預設值可以用 getFieldDecorator 裡的 initialValue。
你不應該用 setState,可以使用 this.props.form.setFieldsValue 來動態改變表單值。
//將editor的html值設為form表單的desc屬性值
this.props.form.setFieldsValue({
'desc': html
});
- 1
- 2
- 3
- 4
- initialValue也會影響必填項的驗證,對於Input元件最好設定為
initialValue:''
.
(2) Form自定義校驗規則:
<FormItem {...formItemLayout} label="描述">
{getFieldDecorator('desc', {
rules: [{
required: true,
message: '請填寫描述',
}, {// 使用自定義的校驗規則
validator: this.validateEditorFrom
}],
initialValue: ''
})(<div ref={(ref) => this._div = ref}></div>)}
</FormItem>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
validateEditorFrom = (rule, value, callback) => {
if (this.state.editorText.trim() === '') {
callback('不能為空');
}
// Note: 必須總是返回一個 callback,否則 validateFieldsAndScroll 無法響應
callback();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
(3) 通過ref獲取元素
<div ref={(ref) => this._div = ref}></div>)
- 1
//獲取真實dom
const elem = ReactDOM.findDOMNode(this._div);
- 1
- 2
React提供的這個ref
屬性,表示為對元件真正例項的引用,其實就是ReactDOM.render()
返回的元件例項;需要區分一下,ReactDOM.render()
渲染元件(這裡指有狀態元件)時返回的是元件例項;而渲染dom元素時,返回是具體的dom節點。 可參考連結:https://blog.csdn.net/z69183787/article/details/69568467
ref可以設定回撥函式(官方推薦)、字串、詳情可參考下一篇連結。
值得注意的是,
- 對於html元素使用ref的情況,ref本身引用的就是該元素的實際dom節點,無需使用ReactDOM.findDOMNode(ref)來獲取,該方法常用於React元件上的ref。
<div ref="divElem">
- 1
this.refs.divElem
即是獲取的dom元素。
- 無法通過ref來獲取無狀態元件例項。
無狀態元件是不會被例項化的,在父元件中通過ref來獲取無狀態子元件時,其值為null。但是可以結合複合元件來包裝無狀態元件來在其上使用ref引用。
<div ref={(node) => refDom = node}>
...
</div>
- 1
- 2
- 3
這樣,可以通過變數refDom來訪問到無狀態元件中的指定dom元素了,訪問其中的其他元件例項類似。
問: 有狀態元件和無狀態元件?
(4)React的key屬性
本案例中Modal中包含key值,react根據key值的變化,判斷是否需要重新載入元件。之前一直遇到Modal顯示時,不觸發componentDidMount()
,從而導致wangeditor不能正確建立的問題,根源就在於modal在index.js頁面載入時就載入了,再顯示時,modal的key值沒有變化,沒有重新載入元件。
react利用key來識別元件,每個key對應一個元件,相同的key react認為是同一個元件,這樣後續相同的key對應元件都不會被建立。
react根據key來決定是銷燬重新建立元件還是更新元件。
- key相同,若元件屬性有所變化,則react只更新元件對應的屬性;沒有變化則不更新。
- key值不同,則react先銷燬該元件(有狀態元件的componentWillUnmount會執行),然後重新建立該元件(有狀態元件的constructor和componentWillUnmount都會執行)
詳情參照部落格: