React富文本编辑器开发(五)

到目前为止我们所有的功能操作都是直接写在 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;

这样代码也清爽了许多,功能我们也抽取出来了,这为我们日后的工具栏的设计创建了基础。效果如下:

相关推荐
jeffwang几秒前
我做了个让 AI 看屏幕跑测试的工具,因为 Playwright 测不了我的 Flutter Web
前端
HSunR30 分钟前
dify 搭建ai作业批改流
开发语言·前端·javascript
代码不加糖38 分钟前
2026 跨境电商独立站实战:从 0 到 1 搭建高转化 SaaS 商城(附源码)
开发语言·前端·javascript
亲亲小宝宝鸭1 小时前
拖一拖控件,拖出个问卷(低代码平台)
前端·低代码
江南十四行1 小时前
ReAct Agent 基本理论与项目实战(一)
前端·react.js·前端框架
We་ct2 小时前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·leetcode·typescript·动态规划
小呆呆6662 小时前
Codex 穷鬼大救星
前端·人工智能·后端
当时只道寻常2 小时前
Vue3 + IntersectionObserver 实现高性能图片懒加载
前端
用户617517157012 小时前
关于普通函数和箭头函数的this
javascript
sakiko_3 小时前
UIKit学习笔记3-布局、滚动视图、隐藏或显示视图
前端·笔记·学习·objective-c·swift·uikit