到目前为止我们所有的功能操作都是直接写在 onKeydown
事件里了,但如果我想复用相同的功能怎么办呢,最好的办法就是拨离
了,下面我就形如进行这样的操作,把相关的可复用的命令操作抽取出来。
新建文件 _helper.jsx
,创建一个协助器
javascript
import { Editor, Transforms, Element } from "slate"
export const Helper = {
// 判断当前是否是粗体状态
isBoldMarkActive(editor) {
const marks = Editor.marks(editor)
return marks ? marks.bold === true : false
},
// 判断当前是否是code状态
isCodeBlockActive(editor) {
const [match] = Editor.nodes(editor, {
match: n => n.type === 'code',
})
return !!match
},
// 切换粗体
toggleBoldMark(editor) {
const isActive = Helper.isBoldMarkActive(editor)
if (isActive) {
Editor.removeMark(editor, 'bold')
} else {
Editor.addMark(editor, 'bold', true)
}
},
// 切换code
toggleCodeBlock(editor) {
const isActive = Helper.isCodeBlockActive(editor)
Transforms.setNodes(
editor,
{ type: isActive ? 'paragraph' : 'code' },
{ match: n => Element.isElement(n) && Editor.isBlock(editor, n) }
)
},
}
这里我们对SDocer.jsx进行修改:
SDocer.jsx
javascript
import { useState, useCallback } from 'react';
import { createEditor, Editor, Transforms, Element } from 'slate';
import { Slate, withReact, Editable } from 'slate-react';
import { initialValue } from './_configure';
import { renderElement } from './_elementRender';
import { renderLeaf } from './_leafRender';
import { Helper } from './_helper';
function SDocer() {
const [editor] = useState(() => withReact(createEditor()));
return (
<Slate editor={editor} initialValue={initialValue}>
<Editable
renderElement={useCallback(renderElement, [])}
renderLeaf={useCallback(renderLeaf, [])}
onKeyDown={event => {
if (!event.ctrlKey) return;
switch (event.key) {
case '`': {
event.preventDefault()
Helper.toggleCodeBlock(editor);
break
}
case 'b': {
Helper.toggleBoldMark(editor);
break
}
}
}}
/>
</Slate>
)
}
export default SDocer;
这样代码也清爽了许多,功能我们也抽取出来了,这为我们日后的工具栏的设计创建了基础。效果如下: