wangEditor富文本编辑器+react+antd的使用(转)

1、github上发现富文本编辑器:

官网地址及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值进行验证,但注意富文本框中输入空格,使用‘ ‘表示,此方法不能处理只输入空格的验证。
    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 (
      "编辑信息"
        width={'60%'}
        confirmLoading={confirmLoading}
        visible={visible}
        onOk={this.submit}
        onCancel={this.props.onCancel}
      >
        
"名称"> {getFieldDecorator('name', { rules: [{ required: true, message: '请填写名称' }], initialValue: '' })()} "描述"> {getFieldDecorator('desc', { rules: [{ required: true, message: '请填写描述', }, {// 使用自定义的校验规则 validator: this.validateEditorFrom }], initialValue: '' })(
this._div = ref}>
)
} FormItem> Col> Row> Form> Modal> ); } } export default MyModal;
  • 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 (
        '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('

哈哈

')进行设置。

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

3、知识点总结

(1) FormItem必填验证,是怎么关联的?

 "名称">
{getFieldDecorator('name', {
rules: [{ required: true, message: '请填写名称' }],
initialValue: ''
})()}

  • 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自定义校验规则:

            "描述">
{getFieldDecorator('desc', {
rules: [{
required: true,
message: '请填写描述',
}, {// 使用自定义的校验规则
validator: this.validateEditorFrom
}],
initialValue: ''
})(
ref={(ref) => this._div = ref}>
)}
  • 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引用。

refDom = node}> ...
  • 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都会执行)

详情参照博客:

        
            

你可能感兴趣的:(java)