draftjs 简介
draftjs 是用于 react 的富文本编辑器框架,它并不能开箱即用,但是它提供了很多用于开发富文本的 API。基于此,开发者能够搭建出定制化的富文本编辑器。draftjs 有几个重要的概念:EditorState、Entity、SelectionState、CompositeDecorator。
EditorState
EditorState 是编辑器的顶级状态对象。它是一个不可变数据,表示 Draft 编辑器的整个状态,包括:
- 当前文本内容状态(ContentState)
- 当前选择状态(SelectionState)
- 内容的装饰器(Decorator)
- 撤销/重做堆栈
- 对内容所做的最新类型的更改(EditorChangeType)
draftjs 基于不可变(immutable)数据,因此对编辑器的修改都需要新生成一个 EditorState 对象传入编辑器,以实现数据更新。
Entity
Entity 用来描述带有元数据的文本,使一段文本可以携带任意类型的数据,提供了更加丰富的功能,链接、提及和嵌入的内容都可以通过 Entity 来实现。
Entity的结构
{
type: 'string',
// 表示Entity的类型; eg:'LINK', 'TOKEN', 'PHOTO', 'IMAGE'
mutability: 'MUTABLE' | 'IMMUTABLE' | 'SEGMENTED',
// 此属性表示在编辑器中编辑文本范围时使用此实体对象注释的文本范围的行为。
data: 'object',
// Entity的元数据; 用于存储你想要存储在该Entity里的任何信息
}
其中 Mutability 这条属性三个值的含义分别是:
- Immutable:此 Entity 作为一个整体,一删则整体都删除,无法更改文本;
- Mutable:Entity 在编辑器中的文字可以自由修改,比如链接文本;
- Segmented:于 Immutable 类似,区别是可以删除部分文字;
SelectionState
SelectionState 表示编辑器中的选择范围。一个选择范围有两点:锚点(起点)和焦点(终点)。
- 锚点位置 === 焦点位置,没有选择文本;
- 锚点位置 > 焦点位置,从右至左选择文本;
- 锚点位置 < 焦点位置,从左至右选择文本;
CompositeDecorator
Decorator 概念的基础是扫描给定 ContentBlock 的内容,根据定义的策略定位到匹配位置,然后用指定的 React 组件呈现它们。
实现一个留言框
首先明确需求:
- 有长度限制,暂定 200 个字;
- 提及(@)时高亮,当用户输入 @ 符号后将 @ 符号后面的文字高亮;
- 插入链接;
先实现一个基础的编辑器:
import React from 'react'
import { Editor, EditorState } from 'draft-js';
import 'draft-js/dist/Draft.css';
import './App.css';
function MyEditor() {
const [editorState, setEditorState] = React.useState(
() =&g