首页/文章/富文本

嗯?绝不允许你还没有属于自己的富文本编辑器

2023-10-16
10844 分钟
...

作为一名新时代农民工,几乎每个人都有自己的博客站点,而博客最重要的功能就是文档编辑,实现文档编辑无外乎Markdown富文本编辑器两种模式。其中富文本编辑器使用起来比较简单,不需要额外了解各种语法,对非技术人员来说容易上手,本文就着重介绍一下富文本编辑器框架————Slate,它不仅可以帮助我们自定义实现富文本效果,而且还能实现类似于Markdown一样的语法输入。

说起Slate,可能很多人不了解,但是说起前端富文本插件库wangEditor以及飞书文档,大家就不陌生了,这两款产品底层技术采用的就是Slate

安装

Slate 本身是支持各种框架的,但是官方提供了React版本的库实现,我们就以React版本示例:

npm install slate slate-react

初始化编辑器

初始化编辑节点,并赋予编辑器默认内容。

注意默认内容的数据结构需要符合Slate的格式,其基本元素类型类似于HTML,包括块节点(Blocks)、行内节点(inlines)。可以通过type字段区分不同的元素,后续我们的自定义节点就可以通过该字段区分。

// index.js 
import { useState } from "react";  
import { createEditor } from "slate"; 
import { Slate, Editable, withReact } from "slate-react"; 
import './index.css'  
const SlateBox = (  ) => {   
  const [editor] = useState(() => withReact(createEditor()))   
  const [editorText, setEditorText] = useState([   
    {      
      type: 'paragraph',     
      children: [{ 
        text: '这是一个slate内容的结构示例,每一段都是通过文本节点或者自定义节点的数组组成,文本节点必须包含text属性。' }]   
    }   
  ])    
  return (   
    <Slate editor={editor} initialValue={editorText}>   
    <Editable className="editor-container" />    
      </Slate>  
)
} 
export default SlateBox;

优化编辑器样式:

/* index.css */ 
*{   
  box-sizing: border-box; 
} 
.editor-container{ 
  width: 100vw;  
  height: 100vh;  
  padding: 8px;  
  background: #000; 
  color: #fff; 
}

目前的效果图:

添加工具栏

富文本编辑器就是通过各种快捷按钮实现文本的不同效果,因此我们在编辑器顶部添加一个工具栏,展示一个高亮块按钮。

js

复制代码

`// index.js import { useState } from "react";  import { createEditor } from "slate"; import { Slate, Editable, withReact } from "slate-react"; import { Button } from 'antd' import { BulbOutlined } from '@ant-design/icons' import './index.css'  const SlateBox = (  ) => {   const [editor] = useState(() => withReact(createEditor()))   const [editorText, setEditorText] = useState([     {       type: 'paragraph',       children: [{ text: '这是一个slate内容的结构示例,每一段都是通过文本节点或者自定义节点的数组组成,文本节点必须包含text属性。' }]     }   ])    const addHighBlock = (  ) => {     console.log('添加高亮块')   }    return (     <Slate editor={editor} initialValue={editorText}>       <div className="editor-toolbar">         <Button icon={<BulbOutlined />} className="menu-btn" type="text" onClick={addHighBlock}></Button>       </div>       <Editable className="editor-container" />     </Slate>   ) }  export default SlateBox;`

实现工具栏样式:

css

复制代码

`/* index.css */ *{   box-sizing: border-box; } .editor-toolbar{   background: #242426;   height: 40px;   display: flex;   align-items: center;   padding: 0 8px; } .menu-btn{   color: #fff !important; } .menu-btn:hover{   background: #000 !important; } .editor-container{   width: 100vw;   height: calc(100vh - 40px);   padding: 8px;   background: #000;   color: #fff;   border: 1px solid transparent; } .editor-container:focus-visible{   outline: none;   border-color: #fff; }`

如约而至的效果图:

重点来了,自定义我们的高亮节点

Slate提供了一个reanderElement方法,通过修改节点数据结构的type类型或者添加属性,就可以让我们轻松实现一个自定义节点。

js

复制代码

`// index.js import { useCallback, useState } from "react";  import { createEditor, Transforms } from "slate"; import { Slate, Editable, withReact, DefaultElement } from "slate-react"; import { Button } from 'antd' import { BulbOutlined } from '@ant-design/icons' import './index.css'  // 自定义高亮节点 const HighBlock = (props) => {   return (     // 添加slate相关属性     <div className="high-block" {...props.attributes}>       <BulbOutlined />       {/* 展示高亮节点下的内容 */}       {props.children}     </div>   ) }  const SlateBox = (  ) => {   const [editor] = useState(() => withReact(createEditor()))   const [editorText, setEditorText] = useState([     {       type: 'paragraph',       children: [{ text: '这是一个slate内容的结构示例,每一段都是通过文本节点或者自定义节点的数组组成,文本节点必须包含text属性。' }]     }   ])   const renderElement = useCallback(props => {     switch (props.element.type) {       case 'highBlock':         return <HighBlock {...props} />       default:         return <DefaultElement {...props} />     }   }, [])    const addHighBlock = (  ) => {     Transforms.insertNodes(editor, { type: 'highBlock', children: [{ text: '高亮节点默认值' }] })   }    return (     <Slate editor={editor} initialValue={editorText}>       <div className="editor-toolbar">         <Button icon={<BulbOutlined />} className="menu-btn" type="text" onClick={addHighBlock}></Button>       </div>       <Editable className="editor-container" renderElement={renderElement} />     </Slate>   ) }  export default SlateBox;`

添加我们自定义节点的样式:

css

复制代码

`/* index.css */ *{   box-sizing: border-box; } .editor-toolbar{   background: #242426;   height: 40px;   display: flex;   align-items: center;   padding: 0 8px; } .menu-btn{   color: #fff !important; } .menu-btn:hover{   background: #000 !important; } .editor-container{   width: 100vw;   height: calc(100vh - 40px);   padding: 8px;   background: #000;   color: #fff;   border: 1px solid transparent; } .editor-container:focus-visible{   outline: none;   border-color: #fff; } .high-block{   display: flex;   padding: 16px;   border-radius: 8px;   background: rgba(242, 150, 44, .17);   border: 1px solid #845117;   margin: 16px 0;   line-height: 24px; } .high-block .anticon-bulb{   color: #eb8f26;   line-height: 28px;   margin-right: 4px; }`

最后的实现效果图

以上只是一个Slate的简单入门示例,它还提供了许多诸如对选区、路径等操作方法,轻松实现滑动选择文字出现文字多音字提示等功能,大家可以去探索一下。

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
富文本2025-01-04
Monaco Editor,代码编辑器神器
本文介绍了 Monaco Editor 这款微软开源的基于浏览器的代码编辑器,它功能强大,包括语法高亮、代码补全等,具有轻量、可定制、跨平台等特点。文中阐述了其应用场景、使用方法、基本概念等,还列举了类似项目并给出项目地址,适合多种开发需求。 关联问题: Monaco支持哪些语言 如何定制Monaco 怎样优化界面效果 Monaco Editor是微软开源的一款基于浏览器的代码编辑器,它源自于Visual Studio Code(简称V...
学习
富文本2024-09-02
富文本格式粘贴的问题
回到最初的问题,利用富文本编辑器,编写邮件模板,或者说,提供一个编辑器,用来编写邮件。如果说编写邮件而已,大可以在 word 或者其他编辑器里写好内容,但这里的一个特点就是 占位符 。所以说,这是要保持邮件编辑器的功能,然后还能使用占位符。 前面也是利用了 实现了 占位符 ,且具有不可编辑的特点。另外也具有了编辑器的基础功能,如文字大小、颜色、背景、居中、缩进等等。在开发中,只关注于编辑器本身,即这个编辑器能编辑就可以了,忽略了 这个功...
学习
富文本2024-05-09
vue3集成tinymce
简介 看了一圈富文本编辑器,发现 和 比较符合自己的需求,功能上 更加丰富、简单一些。 吐槽 吐槽一下 的官网,给了 这个组件包,但是没想到就只是简单包装了一下(期初以为下载完这个包,引入vue组件内就完成了!),没想到如果只是单独引入这个包,是需要 的,而且是云托管方式去下载 ,导致反复看官网折腾了好久! 自托管集成方式 有两种方式,一种是使用包管理工具、另一种是zip包。 ,因为 还是挺大的,开发和打包过程影响编译时间。 以下面技术...
学习
富文本2024-05-08
新一代富文本编辑器框架lexical入门
是一款 基于 开发的网页端文本编辑框架,具备高拓展性架构,以高可靠性、易用性以及性能表现为核心设计思想。本身不与任何框架绑定,可独立于 、 使用(不过由于 与 的亲和性, 有 版)。使用者可在其基础上建立属于自己的独一无二的文本编辑器 目前在 内部,每天 通过 、 、 、 、 等产品服务千百万用户,稳定性及可靠性值得信赖 的核心包(上图左侧部分)只有22kb,其余能力以 形式提供。框架支持延迟加载, 可以在用户真正操作编辑器的时候再加载...
学习
富文本2024-05-06
再遇协同编辑:Yjs + Quill,文档协同编辑竟如此简单
通过上一篇文章 ,相信各位小伙伴对 OT 和 CRDT 协同算法有了一定的了解,并且对 Yjs 有了初步的认识,本文主要教会大家如何使用 Yjs 来实现 Quill 的协同编辑,以及针对 Yjs 的一些重要概念进行讲解。 因为协作需要服务端的支持,所有没有 demo,具体实现请 。 Yjs 介绍 官方介绍: 用于构建 Google Docs 和 Figma 等协作应用程序的模块化构建块 。 基于 CRDT ,帮助实现高性能的协作应用程序...
学习
富文本2024-04-25
Vue使用wangEditor富文本编辑器报错(ot find a descendant at path [0,1] in node: {“children“:[{“type“:“paragraph)_cannot find a descendant at path [0,1] in node
答案 时渲染dom报错问题: 每题的答案 修改文字样式后切换报错 解决办法: 在动态切换答案回显的同时删除 wangEditor 的实例然后异步重新创建一遍进行回显 代码片段:
学习

评论

请登录后发表评论

去登录
加载评论中...

目录