改造wangEditor成react组件

微信扫一扫,分享到朋友圈

改造wangEditor成react组件

我们知道wangEditor常用的功能是editor实例的 txt.html()txt.text() 方法,尤其是 txt.html() 方法,这是一个类似与jQuery常用的那种get和set一体的方法。

我们怎么把这种传统模式书写的第三方库引入到react项目中,并且方便其它同事使用呢?我们需要做一个react组件,让它来完成wangEditor的“react化”。

对于编辑器这种,我们不太在乎它的生命周期,我们更适合将它封装成函数式组件。

我们在项目使用是只有使用 ref 拿到这个组件并且调用对应的方法来取到(设置)富文本里面的内容。

<WangEditor
ref={this.richEditorRef}
content={this.state.editShortcutReply.content}/>

这样在使用时就很方便啊,那我们的WangEditor组件怎么实现呢?

import React, { useEffect, forwardRef, useImperativeHandle } from 'react';
import toaster from 'viewsUI/toaster';
import WangEditor from 'viewsUI/wangeditor/wangEditorForSetting'
import wangEditorI18nLang from './i18nLang';
let richEditor = null;
/*eslint-disable*/
const wangEditor = (props, ref) => {
let unique = Math.random().toString(36).substr(2);
useEffect(() => {
console.log('wangEditor useEffect -> ');
loadEditor();
if (props.visible) {
setContent(props.content || '');
}
}, []);
function getContent() {
return richEditor.txt.html();
}
function getText() {
return richEditor.txt.text();
}
function setContent (content) {
richEditor.txt.html(content);
initFocus();
}
function initFocus() {
const $textElem = richEditor.$textElem;
const $children = $textElem.children();
if ($children.length) {
const $first = $children.first();
richEditor.selection.createRangeByElem($first, false, true);
richEditor.selection.restoreSelection();
}
}
useImperativeHandle(ref, () => ({
getContent,
getText,
setContent,
initFocus,
}));
function loadEditor() {
richEditor = new WangEditor('#toolbar' + unique, '#body' + unique);
richEditor.customConfig.uploadImgShowBase64 = false;
richEditor.customConfig.uploadImgMaxLength = 1
richEditor.customConfig.uploadImgParams = {
fileBytes: '',
maxBytes: 204800,
thumbHeight: 120,
thumbWidth: 120,
};
richEditor.customConfig.menus = [
'head', // 标题
'bold', // 粗体
'fontSize', // 字号
'fontName', // 字体
'italic', // 斜体
'underline', // 下划线
// 'strikeThrough', // 删除线
'foreColor', // 文字颜色
'backColor', // 背景颜色
'link', // 插入链接
'list', // 列表
'justify', // 对齐方式
'quote', // 引用
//'emoticon', // 表情
'image', // 插入图片
// 'table', // 表格
'htmlTable', // 粘贴表格
// 'video', // 插入视频
// 'code', // 插入代码
'undo', // 撤销
'redo' // 重复
];
richEditor.create();
}
return (
<div  style={{display: 'flex','flexDirection': 'column',width: '100%', height: '100%', overflow: 'auto'}}>
<div id={'toolbar' + unique} style={{borderBottom: '1px solid #EBF2FA', fontSize: '14px', padding: '5px 10px', marginBottom: '5px', flex: 'none' }}/>
<div id={'body' + unique} style={{height: 'auto',wordBreak: 'break-all',whiteSpace: 'normal',flex: 'auto',display: 'flex',flexDirection: 'column', overflow: 'auto'}}/>
</div>
);
};
export default forwardRef(wangEditor);

为了给父组件暴露wangEditor组件的部分方法,我们需要使用 useImperativeHandle

它可以让你在使用 ref 时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。 通常 useImperativeHandle 应当与 forwardRef 一起在函数式中使用。

forwardRef介绍

用法一:让我们在父组件里面能通过 ref 拿到函数式子组件的某个node节点

const Menu = (props, ref) => {
return (<aside ref={ref}  id="menu" className={props.show ? 'show' : ''}>
<div className="inner flex-row-vertical">
<Profile avatarUrl="/owner.jpg"/>
<div className="scroll-wrap flex-col">
<MenuList asides={props.asides}/>
<ArchiveList />
</div>
</div>
</aside>);
};
export default forwardRef(Menu);

具体使用细节可以参照我前几天写的 《Did you mean to use React.forwardRef()?搞懂react的createRef和forwardRef》

用法二:让我们在父组件里面能通过 ref 拿到函数式子组件需要通过 useImperativeHandle 暴露的方法

const Menu = (props, ref) => {
function log(...rest) {
console.log(...rest);
}
useImperativeHandle(ref, () => ({
log
}));
return (<aside ref={ref}  id="menu" className={props.show ? 'show' : ''}>
<div className="inner flex-row-vertical">
<Profile avatarUrl="/owner.jpg"/>
<div className="scroll-wrap flex-col">
<MenuList asides={props.asides}/>
<ArchiveList />
</div>
</div>
</aside>);
};
export default forwardRef(Menu);

useImperativeHandle介绍

useImperativeHandle(ref, createHandle, [deps])

ref :定义 current 对象的 ref createHandle :一个函数,返回值是一个对象,即这个 ref 的current [deps] :即依赖列表,当监听的依赖发生变化,useImperativeHandle 才会重新将子组件的实例属性输出到父组件ref 的 current 属性上,如果为空数组,则不会重新输出。

现在我们就可以通过 this.richEditorRef.current.getContent() 获取到富文本里面的内容了。

微信扫一扫,分享到朋友圈

改造wangEditor成react组件

Vue3 中的 getter 和 setter 源码简解

上一篇

golang 进度条功能实现

下一篇

你也可能喜欢

改造wangEditor成react组件

长按储存图像,分享给朋友