1. 程式人生 > >wangEditor富文字編輯器+react+antd的使用(轉)

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 函式監聽內容的變化,並實時更新到 stateeditor
.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值進行驗證,但注意富文字框中輸入空格,使用‘&nbsp‘表示,此方法不能處理只輸入空格的驗證。 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都會執行)

詳情參照部落格: