扫一扫分享
使用浏览器提供的 contenteditable 属性让一个 dom 节点具有可编辑能力。
引擎接管了浏览器大部分光标、事件等默认行为。
可编辑器区域内的节点通过 schema 规则,制定了 mark inline block card 4 种组合节点,他们由不同的属性、样式或 html 结构组成,并对它们的嵌套进行了一定的约束。
通过 MutationObserver 监听编辑区域内的 DOM 树的改变,并生成 json0 类型的数据格式与 ShareDB 库进行交互,从而达到协同编辑的需要。
编辑器由 引擎、工具栏、插件 组成。引擎 为我们提供了核心的编辑能力。
使用 npm 或者 yarn 安装引擎包
$ npm install @aomao/engine
# or
$ yarn add @aomao/engine
我们按照惯例先输出一个Hello word!
import React, { useEffect, useRef, useState } from 'react';
import Engine, { EngineInterface } from '@aomao/engine';
const EngineDemo = () => {
//编辑器容器
const ref = useRef<HTMLDivElement | null>(null);
//引擎实例
const [engine, setEngine] = useState<EngineInterface>();
//编辑器内容
const [content, setContent] = useState<string>('<p>Hello word!</p>');
useEffect(() => {
if (!ref.current) return;
//实例化引擎
const engine = new Engine(ref.current);
//设置编辑器值
engine.setValue(content);
//监听编辑器值改变事件
engine.on('change', (value) => {
setContent(value);
console.log(`value:${value}`);
});
//设置引擎实例
setEngine(engine);
}, []);
return <div ref={ref} />;
};
export default EngineDemo;
引入 @aomao/plugin-bold 加粗插件
import Bold from '@aomao/plugin-bold';
把 Bold 插件加入引擎
//实例化引擎
const engine = new Engine(ref.current, {
plugins: [Bold],
});
卡片是编辑器中单独划分的一个区域,其 UI 以及逻辑在卡片内部可以使用 React、Vue 或其它前端库自定义渲染内容,最后再挂载到编辑器上。
引入 @aomao/plugin-codeblock 代码块插件,这个插件的 语言下拉框 使用 React 渲染,所以有区分。 Vue3 使用 @aomao/plugin-codeblock-vue
import CodeBlock, { CodeBlockComponent } from '@aomao/plugin-codeblock';
把 CodeBlock 插件和 CodeBlockComponent 卡片组件加入引擎
//实例化引擎
const engine = new Engine(ref.current, {
plugins: [CodeBlock],
cards: [CodeBlockComponent],
});
CodeBlock 插件默认支持 markdown,在编辑器一行开头位置输入代码块语法```javascript 回车后即可触发。
引入 @aomao/toolbar 工具栏,工具栏由于交互复杂,基本上都是使用 React + Antd UI 组件渲染,Vue3 使用 @aomao/toolbar-vue
工具栏除了 UI 交互外,大部分工作只是对不同的按钮事件触发后调用了引擎执行对应的插件命令,在需求比较复杂或需要重新定制 UI 的情况下,Fork 后修改起来也比较容易。
import Toolbar, { ToolbarPlugin, ToolbarComponent } from '@aomao/toolbar';
把 ToolbarPlugin 插件和 ToolbarComponent 卡片组件加入引擎,它可以让我们在编辑器中可以使用快捷键 / 唤醒出卡片工具栏
//实例化引擎
const engine = new Engine(ref.current, {
plugins: [ToolbarPlugin],
cards: [ToolbarComponent],
});
渲染工具栏,工具栏已配置好所有插件,这里我们只需要传入插件名称即可
return (
...
{
engine && (
<Toolbar
engine={engine}
items={[
['collapse'],
[
'bold',
],
]}
/>
)
}
...
)
手机预览