内容简介:我们知道wangEditor常用的功能是editor实例的我们怎么把这种传统模式书写的第三方库引入到react项目中,并且方便其它同事使用呢?我们需要做一个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() 获取到富文本里面的内容了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Persuasive Technology
B.J. Fogg / Morgan Kaufmann / 2002-12 / USD 39.95
Can computers change what you think and do? Can they motivate you to stop smoking, persuade you to buy insurance, or convince you to join the Army? "Yes, they can," says Dr. B.J. Fogg, directo......一起来看看 《Persuasive Technology》 这本书的介绍吧!