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() class MyModal extends React.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,創新富文字編輯器 var editor = new Editor(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> ); } } export default MyModal;

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}
        />
    );
}

需要設定富文字編輯的內容時,可以在react的componentDidMount生命週期函式中 使用editor.txt.html('<p>哈哈</p>')進行設定。

const value = this.props.data && this.props.data.desc || '';
editor.txt.html(value);

3、知識點總結

(1) FormItem必填驗證,是怎麼關聯的?

 <FormItem {...formItemLayout} label="名稱">
     {getFieldDecorator('name', {
                  rules: [{ required: true, message: '請填寫名稱' }],
                  initialValue: ''
               })(<Input />)}
 </FormItem>

答案可以使用官網的話:

  • 經過 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
        });
  • 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>
validateEditorFrom = (rule, value, callback) => {
    if (this.state.editorText.trim() === '') {
      callback('不能為空');
    }
    // Note: 必須總是返回一個 callback,否則 validateFieldsAndScroll 無法響應
    callback();
  }

(3) 通過ref獲取元素

<div ref={(ref) => this._div = ref}></div>)
//獲取真實dom
const elem = ReactDOM.findDOMNode(this._div);

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">

this.refs.divElem 即是獲取的dom元素。

  • 無法通過ref來獲取無狀態元件例項。

無狀態元件是不會被例項化的,在父元件中通過ref來獲取無狀態子元件時,其值為null。但是可以結合複合元件來包裝無狀態元件來在其上使用ref引用。

<div ref={(node) => refDom = node}>
            ...
</div>

這樣,可以通過變數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都會執行)

詳情參照部落格: