阅读 160

50 行代码 React Hooks 中使用富文本编辑器

前言

继 50 行代码 Vue3 中使用富文本编辑器 之后,继续使用 wangEditor V5 实现 React 富文本编辑器。wangEditor V5 官方提供 React 组件,使用非常简单。

wangEditor V5 正在公开测试中,有问题和建议可以提交到 github issue 。

【注意】编辑器后续可能继续升级,API 和配置或许会调整。所以问题请及时查阅文档,不要仅依赖本文。

安装

使用 create-react-app 创建一个 React 开发环境,然后安装 wangEditor 必要的包

yarn add @wangeditor/editor yarn add @wangeditor/editor-for-react 复制代码

创建编辑器

写代码

创建 React 组件 MyEditor.js,代码如下,大约 50 行,逻辑也非常简单。(源码在文章最后)

import React, { useState, useEffect } from 'react' import '@wangeditor/editor/dist/css/style.css' import { Editor, Toolbar } from '@wangeditor/editor-for-react' export default function MyEditor() {     const [editor, setEditor] = useState(null) // 存储 editor 实例     const defaultContent = [] // 编辑器默认内容,空内容          const toolbarConfig = {} // 菜单栏配置          // 编辑器配置     const editorConfig = {         placeholder: '请输入内容...',         onCreated: (editor) => {             // 编辑器创建之后,记录 editor 实例,重要 !!! (有了 editor 实例,就可以执行 editor API)             setEditor(editor)         },         onChange: (editor) => {             // editor 选区或者内容变化时,获取当前最新的的 content             console.log('changed', editor.children)         }     }          // 组件销毁时,及时销毁 editor 实例,重要!!!     useEffect(() => {         return () => {             if (editor == null) return             editor.destroy()             setEditor(null)         }     }, [editor])          return (         <div style={{ border: '1px solid #ccc', zIndex: 100}}>             {/* 渲染 toolbar */}             <Toolbar                 editor={editor}                 defaultConfig={toolbarConfig}                 style={{ borderBottom: '1px solid #ccc' }}             />             {/* 渲染 editor */}             <Editor                 defaultConfig={editorConfig}                 defaultContent={defaultContent}                 style={{ height: '500px' }}             />         </div>     ) } 复制代码

运行

把这个组件引入到 App.js 中,即可生成一个功能齐全的富文本编辑器。当编辑器内容发生变化时,会触发 onChange 打印编辑器最新内容。

image.png

注意事项

  • 传入编辑器的默认内容 defaultContent 必须是 JSON 格式(不能是 html),数据结构参考这里

  • onCeated 时记录 editor 实例,方便后续执行 API

  • 组件销毁时,及时销毁 editor 防止内存泄漏

ajax 异步获取内容,再创建编辑器

定义一个 state isAjaxDone 来表示 ajax 是否请求完成,然后根据 isAjaxDone 的值来判断是否渲染编辑器。

// const defaultContent = [] const [defaultContent, setDefaultContent] = useState([]) const [isAjaxDone, setIsAjaxDone] = useState(false) // 模拟 ajax 请求 setTimeout(() => {     setDefaultContent([         {             type: "paragraph",             children: [{ text: "ajax 异步获取的内容" }],         }     ])     setIsAjaxDone(true) }, 1500) return (     <div style={{ border: '1px solid #ccc', zIndex: 100}}>         {/* 待 ajax 请求结束,再渲染 toolbar */}         {isAjaxDone && <Toolbar ... />}         {/* 待 ajax 请求结束,再渲染 editor */}         {isAjaxDone && <Editor ... />}     </div> ) 复制代码

配置

编辑器配置

上文代码中只配置了 placeholder onCreated onChange 作为示例。它还支持 readOnly autoFocus maxLength 等配置,可参考文档。

const editorConfig = {     placeholder: '请输入内容...',     onCreated: editor => {},     onChange: editor => {},     // 继续其他配置 } 复制代码

工具栏配置

如果你想修改工具栏的菜单,如隐藏某些菜单,重新排序分组,就可以使用该配置。支持 toolbarKeys 和 excludeKeys,可参考文档。

const toolbarConfig = {     toolbarKeys: [ /* 显示哪些菜单,如何排序、分组 */ ],     excludeKeys: [ /* 隐藏哪些菜单 */ ], } 复制代码

菜单配置

如果你想对某个菜单进行配置,例如配置颜色、字体、字号,配置上传图片的 API 地址等,可以使用菜单配置。具体参考文档。

const editorConfig = {     // 编辑器配置,如 placeholder onChange ...     // 所有的菜单配置,都要在 MENU_CONF 属性下     MENU_CONF: {         // 配置字号         fontSize: [ ... ],         // 配置上传图片         uploadImage: { ... },         // 继续其他菜单配置     } } 复制代码

API

wangEditor 提供了丰富的 API ,可以帮助你进行任何编辑器操作。可参考文档。

  • 配置相关的 API

  • 内容处理相关的 API

  • 节点操作相关的 API

  • 选区操作相关的 API

  • 自定义事件的 API

我们在上述代码中,已经在 onCreated 时记录了 editor 实例,所以想使用 API ,直接在 editor 上执行即可。

function getEditorText() {     if (editor == null) return // editor 在上述代码中已经定义     console.log(editor.getText()) // 使用 editor API } return <>     <button onClick={getEditorText}>getText</button>          <div style={{ border: '1px solid #ccc', zIndex: 100}}>         <Toolbar ... />         <Editor ... />     </div> </> 复制代码

获取内容,存储到服务器

编辑器的内容是 JSON 格式的,例如一段文字的数据格式为:

[{"type":"paragraph","children":[{"text":"文字内容"}]}] 复制代码

通过 editor.children 即可获取内容,ajax 提交到服务器。当然,也可以使用 onChange 把内容同步到 <textarea> 然后用 form 提交。

你可以使用 editor.getHtml() 获取 html 内容。
但请注意,如果仅保存 html 内容,将无法再次编辑。因为编辑器初始化时,仅能传入 JSON 格式的内容,不能传入 html 。

显示内容

从服务端获取编辑器的内容 content ,创建一个 editor 实例,即可获取 html 和纯文本,然后渲染页面。

import { createEditor } from '@wangeditor/editor' const editor = createEditor({     content }) editor.getHtml() editor.getText() 复制代码

PS:如果你想做服务端渲染 SSR ,这段代码也可以在 nodejs 中运行

总结

本文源码在这里。

wangEditor V5 正在公开测试中,有问题和建议可以提交到 github issue 。


作者:王福朋
链接:https://juejin.cn/post/7030584414652334093


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐