绝对不能错过的富文本编辑器,功能强大极了!


大家好,我是徐小夕。之前我和大家分享了许多关于可视化、零代码和前端工程化的最佳实践。最近也在研究可视化文档知识引擎Nocode/WEP的发展。

在探索文档编辑器的过程中,我也发现了不少优秀开源项目,并从中吸取了先进的设计思想。

接下来,我将和大家分享一款由Facebook开源的强大富文本编辑器——Lexical。目前在GitHub上有17.7k颗星。

GitHub地址:https://github.com/facebook/lexical

往期精彩内容:

在过去的三个月中,我独立完成了一个可视化产品的开发工作,并且第三款可视化产品——Dooring零代码搭建平台3.5正式上线了。这标志着我的努力得到了成果。

Next-Admin是一款基于Nextjs开发的开箱即用的中后台管理系统,它提供了一种全新的、简单易用的方式来管理您的业务流程。这款产品从一开始就具备功能完备和性能卓越的特点,为用户提供了一个稳定且可靠的系统环境。

Lexical是一个可扩展的JavaScript文本编辑器框架,它的设计理念是可靠性、可访问性和高性能。我专注于开发用户友好界面,并通过优化文档设计来增强其功能。

在Lexical中,我们关注的是为开发者提供一个良好的工作体验。我们努力确保框架具备高性能和可靠性的特点,从而使文档设计更加容易进行并构建出功能强大的工具。

结合高度可扩展的架构,Lexical 提供了一种独特的文本编辑体验。开发者可以根据需要实现各种功能,这些功能可以通过二次扩展来实现。例如,Lexical 支持多人协作和定制文本插件。这个平台非常适合开发人员进行创新和实验。

我们可以通过它创建类似于Nocode/WEP文档引擎的编辑体验。同时,我们还能轻松地选择和修改文本样式。

同时还能对文本内容进行评论:

当然插入表格和代码等区块也是支持的:

接下来就和大家一起分享以下它的设计思路。

设计思想

Lexical 是一个无依赖的文本编辑器框架,它允许开发人员构建强大、简单和复杂的功能强大的编辑器界面。Lexical 涉及到几个值得探索的概念:

1. **编辑器实例**:编辑器实例是将所有内容连接在一起的核心概念。我们可以通过将 contentEditable DOM 元素附加到编辑器实例,并注册侦听器和命令来创建一个基础的实例。最重要的是,编辑器允许我们更新其 EditorState。

2. **编辑器状态**:编辑器状态是表示要在 DOM 上显示的内容的数据模型。它分为两个部分:

- Lexical 节点树

- Lexical 选择对象

3. **不可变性与更新**:一旦创建,编辑器状态就是不可变的。为了更新它,我们可以通过 editor.update(() => {...}) 来完成。然而,也可以使用节点变换或命令处理程序来“挂钩”到现有更新中,这些处理程序会在现有的更新过程中调用,并且不会导致级联/瀑布更新。此外,我们可以直接通过 editor.getEditorState() 获取当前的编辑器状态。

4. **序列化与解析**:Lexical 的编辑器状态可以完全序列化为 JSON,并使用 editor.parseEditorState()将其轻松地重新序列化为编辑器。

5. **读取和更新编辑器状态**:当需要读取或更新 Lexical 节点树时,我们可以通过 editor.update(() => {...}) 来完成。也可以通过 editor.getEditorState().read(() => {...}) 对编辑器状态进行只读操作。

Lexical的设计模型如下:

- **基础框架**:提供了无依赖的文本编辑器核心。

- **交互组件**:支持多种交互方式,如内容Editable DOM元素、React、Vue等。

- **设计灵活性**:提供丰富的配置选项和自定义能力。

为了让大家更直观地了解编辑器的使用方法,我分享了一个完整的代码案例。

首先,我们需要创建一个编辑器实例。为此,我们定义了配置参数`config`:

```javascript

{

namespace: 'MyEditor',

theme: {

...

},

onError: console.error

}

```

然后,通过调用`createEditor(config)`方法,我们可以获得一个新的编辑器实例。

接下来,我们需要更新编辑器的内容。具体来说,我们创建了一个段落节点和一个文本节点,并将文本节点添加到了段落中。最后,我们将段落插入到编辑器的根节点中:

```javascript

editor.update(() => {

const root = $getRoot();

const selection = $getSelection();

// 创建段落节点

const paragraphNode = $createParagraphNode();

// 创建文本节点

const textNode = $createTextNode('Hello world');

// 添加文本节点到段落

paragraphNode.append(textNode);

// 插入元素

root.append(paragraphNode);

});

```

以上就是通过两步实现的编辑器创建和更新,是不是非常简单?

如果您对这款编辑器感兴趣,也可以在github上学习使用方法。此外,我也欢迎您在留言区与我交流反馈。

更多代码示例请参见我的博客文章《独立开发3个月,第三款可视化产品终于上线了》。

同时,请关注我的其他项目:Nocode/WEP 项目(零代码搭建平台)以及H5-Dooring零代码搭建平台,如果您有任何想法或问题,请随时与我交流。