Skip to content

Node

JuiceEditor 的数据结构主要由 Node 组成,Node 是 JuiceEditor 中最基础的数据结构,所有的内容都是由 Node 组成的。

定义

Node 是一个与编程语言无关的数据结构,为方便说明,用 TypeScript 来定义。

ts
interface Node {
  type: string;
  html?: string;
  text?: string;
  attrs?: Record<string, any>;
  content?: Node[];
}

Node 是一个对象,它包含了以下几个属性:

  • type: 节点类型
  • html: 节点对应的 HTML 字符串
  • text: 节点对应的文本字符串
  • attrs: 节点对应的属性
  • content: 节点包含的子节点

节点类型

JuiceEditor 中的节点类型众多,且可能会增加,主要的有:

  • root:根节点,所有节点都包含在根节点中
  • text:文本节点,是最基础的节点,无子节点
  • paragraph:段落节点,包含文本节点
  • heading:标题节点,包含文本节点
  • list:列表节点
  • quote:引用节点

HTML

仅 root 节点有 html 属性,其他节点没有。

如:

ts
const node: Node = {
  type: 'root',
  html: '<div data-type="root"><h1>Hello, world!</h1><p>This is a paragraph.</p></div>',
};

HTML 存储了文档的所有数据,可以和 Root 节点相互转换。

以上例子转换成 Root 节点后为:

ts
{
  type: 'root',
  content: [
    { 
        type: 'heading', 
        attrs: { level: 1 }, 
        content: [{ type: 'text', text: 'Hello, world!' }] 
    },
    { 
        type: 'paragraph', 
        content: [{ type: 'text', text: 'This is a paragraph.' }] 
    }
  ]
};

将上述数据存入数据库,有时候需要将其扁平化,转换成多个 Node 的数组。

ts
const nodes: Node[] = [
  { type: 'root' },
  { type: 'heading', attrs: { level: 1 } },
  { type: 'text', text: 'Hello, world!' },
  { type: 'paragraph' },
  { type: 'text', text: 'This is a paragraph.' }
];

在数据库中表现为多行数据:

idtypetextparent_id
1rootnullnull
2headingnull1
3text'Hello, world!'2
4paragraphnull1
5text'This is a paragraph.'4