内容简介:我们知道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()
获取到富文本里面的内容了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Java 对象属性复制组件:Mapstruct 的项目改造指南
- 【CuteJavaScript】Angular6入门项目(4.改造组件和添加HTTP服务)
- 不改造HBase就能应对复杂查询场景?这个索引组件亮了丨自研出圈
- 项目容器化改造心得
- 遗留系统改造-开篇
- 全链路压测改造
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入理解LINUX内核(第三版)
(美)博韦,西斯特 / 陈莉君;张琼声;张宏伟 / 中国电力出版社 / 2007-10-01 / 98.00元
为了彻底理解是什么使得Linux能正常运行以及其为何能在各种不同的系统中运行良好,你需要深入研究内核最本质的部分。内核处理CPU与外界间的所有交互,并且决定哪些程序将以什么顺序共享处理器时间。它如此有效地管理有限的内存,以至成百上千的进程能高效地共享系统。它熟练地统筹数据传输,这样CPU 不用为等待速度相对较慢的硬盘而消耗比正常耗时更长的时间。 《深入理解Linux内核,第三版》指导你对内核......一起来看看 《深入理解LINUX内核(第三版)》 这本书的介绍吧!