业务型 编辑器组件的封装(复制即可使用)

使用需要安装 wangeditor npm i --save wangeditor

javascript 复制代码
import React from 'react';
import E from 'wangeditor';
import './index.less'

class EditorElem extends React.Component {

    constructor(props) {
        super(props);
        this.isChange = false;
        this.state = {
        }

    }
    componentDidMount() {
        const elemBody = this.refs.editorElemBody;
        this.editor = new E(elemBody)
        this.initEditor()
    }
    componentWillReceiveProps(nextProps) {

        if (nextProps.value != this.props.value) {
            if (!this.isChange) {
                this.editor.txt.html(nextProps.value)
            }
            this.isChange = false;
        }
    }

    initEditor() {
        // 使用 onchange 函数监听内容的变化,并实时更新到 state 中
        this.editor.config.onchange = html => {
            this.isChange = true;
            // console.log(editor.txt.html())
            let editorContent = this.editor.txt.html();
            this.props.onChange(editorContent)
            // 不给延时,会导致详情调整过的内容修改后组件数据更新不了
            setTimeout(() => {
                this.isChange = false
            }, 50);
        }
        this.editor.config.menus = [
            'head', // 标题
            'bold', // 粗体
            'fontSize', // 字号
            'fontName', // 字体
            'italic', // 斜体
            'underline', // 下划线
            'strikeThrough', // 删除线
            'indent',
            'lineHeight',
            'foreColor', // 文字颜色
            'backColor', // 背景颜色
            'link', // 插入链接
            'list', // 列表
            'todo',
            'justify', // 对齐方式
            'quote', // 引用
            'emoticon', // 表情
            'image', // 插入图片
            'table', // 表格
            'video', // 插入视频
            'code', // 插入代码
            'splitLine',
            'undo', // 撤销
            'redo' // 重复
        ]
        this.editor.config.colors = ['#999', '#666', '#000000',
            '#eeece0',
            '#1c487f',
            '#4d80bf',
            '#c24f4a',
            '#8baa4a',
            '#7b5ba1',
            '#46acc8',
            '#f9963b',
            '#ffffff'];
        // editor.config.uploadImgShowBase64 = true;
        this.editor.config.pasteIgnoreImg = true;
        this.editor.config.uploadImgServer = `${configs.host.test}/api/FileUpload/Upload`;  // 上传图片到服务器 
        this.editor.config.uploadFileName = 'fileName'
        this.editor.config.uploadImgParams = {
            merchantId: localStorage.getItem('MerchantId'),
            Directory: 'Image'
        }
        // 限制一次最多上传 1 张图片
        this.editor.config.uploadImgMaxLength = 1;
        // 将 timeout 时间改为 3s
        // this.editor.config.uploadImgTimeout = 3000;
        this.props.zIndex && (this.editor.config.zIndex = this.props.zIndex);
        this.editor.config.uploadImgHeaders = {
            Accept: 'multipart/form-data',
            // Authorization: `Bearer ${localStorage.getItem('access_token')}`,
            // MerchantId: localStorage.getItem('MerchantId')
        }
        this.editor.config.uploadImgHooks = {
            before: function (xhr, editor, files) {
                // 图片上传之前触发
            },
            success: function (xhr, editor, result) {
                // 图片上传并返回结果,图片插入成功之后触发
            },
            fail: function (xhr, editor, result) {
                // 图片上传并返回结果,但图片插入错误时触发
            },
            error: function (xhr, editor) {
                // 图片上传出错时触发
            },
            // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
            // (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
            customInsert: function (insertImg, result, editor) {
                // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
                // insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
                // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
                var url = result.data;
                insertImg(url);
                // result 必须是一个 JSON 格式字符串!!!否则报错
            }
        }
        this.editor.create()
        this.props.value && this.editor.txt.html(this.props.value);
        // 开启编辑功能
        if (this.props.disabled) {
            this.editor.disable()
        }
        // this.editor.$textElem.attr('contenteditable', this.props.disabled ? false : true)
    }
    render() {
        return (
            <div className="text-area" >
                <div
                    style={{
                        // height: 335,
                    }}
                    ref="editorElemBody" className="editorElem-body">

                </div>
            </div>
        )
    }
}

export default EditorElem;
css 复制代码
.editorElem-body{
    /* table 样式 */
table {
    border-top: 1px solid #ccc;
    border-left: 1px solid #ccc;
  }
  table td,
  table th {
    border-bottom: 1px solid #ccc;
    border-right: 1px solid #ccc;
    padding: 3px 5px;
  }
  table th {
    border-bottom: 2px solid #ccc;
    text-align: center;
  }
  
  /* blockquote 样式 */
  blockquote {
    display: block;
    border-left: 8px solid #d0e5f2;
    padding: 5px 10px;
    margin: 10px 0;
    line-height: 1.4;
    font-size: 100%;
    background-color: #f1f1f1;
  }
  
  /* code 样式 */
  code {
    display: inline-block;
    *display: inline;
    *zoom: 1;
    background-color: #f1f1f1;
    border-radius: 3px;
    padding: 3px 5px;
    margin: 0 3px;
  }
  pre code {
    display: block;
  }
  
  /* ul ol 样式 */
  ul, ol {
    margin: 10px 0 10px 20px;
  }
}
css 复制代码
 {/* 编辑器组件 ---开始 */}
                <FormItem {...formItemLayout2} label="编辑器组件">
                  {getFieldDecorator("editorValue", {
                    rules: [{ required: true, message: "请填写内容" }],
                    initialValue: detailData.editorValue,
                  })(<EditorElemItem />)}
                </FormItem>
                {/* 编辑器组件 ---结束 */}

使用便捷,无需关注内部实现和定义一堆函数,只需要传入value值 即可回显数据

可以触发form的表单验证,无需额外在提交的时候验证是否有值进行message提示

相关推荐
qq_177767372 分钟前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos
烬头88215 分钟前
React Native鸿蒙跨平台应用实现了onCategoryPress等核心函数,用于处理用户交互和状态更新,通过计算已支出和剩余预算
前端·javascript·react native·react.js·ecmascript·交互·harmonyos
程序员清洒2 小时前
Flutter for OpenHarmony:Text — 文本显示与样式控制
开发语言·javascript·flutter
雨季6662 小时前
Flutter 三端应用实战:OpenHarmony 简易“动态内边距调节器”交互模式深度解析
javascript·flutter·ui·交互·dart
天人合一peng2 小时前
Unity中button 和toggle监听事件函数有无参数
前端·unity·游戏引擎
会飞的战斗鸡3 小时前
JS中的链表(含leetcode例题)
javascript·leetcode·链表
方也_arkling3 小时前
别名路径联想提示。@/统一文件路径的配置
前端·javascript
毕设源码-朱学姐3 小时前
【开题答辩全过程】以 基于web教师继续教育系统的设计与实现为例,包含答辩的问题和答案
前端
qq_177767373 小时前
React Native鸿蒙跨平台剧集管理应用实现,包含主应用组件、剧集列表、分类筛选、搜索排序等功能模块
javascript·react native·react.js·交互·harmonyos
qq_177767374 小时前
React Native鸿蒙跨平台自定义复选框组件,通过样式数组实现选中/未选中状态的样式切换,使用链式调用替代样式数组,实现状态驱动的样式变化
javascript·react native·react.js·架构·ecmascript·harmonyos·媒体