文档内脑图, WORD 脑图扩展

526 字
3 分钟
文档内脑图, WORD 脑图扩展

需求:WORD 中不涉及具体脑图代码、只渲染需要操作的脑图(性能)、兼容历史记录

  1. 属性:height、脑图 ID、脑图快照。默认显示快照,选中后再渲染脑图

    addAttributes() {
    return {
    height: { // 默认半屏高
    default: '50vh'
    },
    'mind-id': {
    default: ''
    },
    snapshot: { // 默认快照
    default: 'https://faworkfile.xxx.cn/userUpload/docs/rjU0JlwXSfvtcdjiGExIQgQIczZUExReBjOcqzTI.svg'
    }
    }
    },
  2. 方法:插入脑图、更新脑图、删除脑图。插入脑图时发送创建请求,请求失败删除脑图,成功以 addToHistory:false 更新脑图

    addCommands() {
    return {
    // prettier-ignore
    setMind: () => ({ commands, editor }) => {
    api_create_mind().then((mindId: string) => {
    // 更新ID
    editor.commands.updateMind({ oldId: mindIngId, newId: mindId })
    }).catch(err => {
    ElMessage.error(err.message)
    // 删除节点
    editor.commands.removeMind(mindIngId)
    })
    const mindIngId = `ing-${uuidv4()}` // 创建中的临时ID
    return commands.insertContent({
    type: this.name,
    attrs: { 'mind-id': mindIngId }
    })
    },
    // prettier-ignore
    updateMind: ({ oldId, newId }) => ({ tr }) => {
    let currPos = -1
    tr.doc.nodesBetween(0, tr.doc.content.size, (node, pos) => {
    if (currPos !== -1 || node.type.name !== this.name) return false
    if (node.attrs['mind-id'] !== oldId) return false
    currPos = pos
    })
    if (currPos > -1) {
    // 以 不要历史记录的方法 更新脑图ID
    tr.setMeta('addToHistory', false)
    tr.setNodeMarkup(currPos, undefined, { 'mind-id': newId })
    }
    return true
    },
    // prettier-ignore
    removeMind: (mindId: string) => ({ tr, state }) => {
    let currPos = -1
    tr.doc.nodesBetween(0, tr.doc.content.size, (node, pos) => {
    if (currPos !== -1 || node.type.name !== this.name) return false
    if (node.attrs['mind-id'] !== mindId) return false
    currPos = pos
    })
    if (currPos > -1) {
    // 删除脑图节点
    tr.replaceWith(currPos, currPos + 1, state.schema.nodes.paragraph.create())
    }
    return true
    }
    }
    },
  3. QtableMind.vue

    a. ID 为临时 ID 显示空节点 b. 节点未聚焦显示快照(一张图片,在顶层),一个空 DIV <div class="mind-node" :data-id="mindId"></div> c. 节点聚焦,发送 statusChange 事件给 web 项目 { type: ‘renderMind’, payload: mindId } • web 项目收到后调用 mind/InDoc.vue • mind/InDoc.vue 组件以 <teleport to='.mind-node[data-id="mindId"]'> 方式渲染进 WORD • MIND 渲染完成后发送自定义事件 mindRendered • onBeforeUnmount 钩子中生成脑图快照 base64 d. 收到 mindRendered 事件隐藏快照 e. 节点失焦,发送 statusChange 事件给 web 项目 { type: ‘renderMind’, payload: ” } • web 项目收到后删除 mind/InDoc.vue • mind/InDoc.vue onBeforeUnmount 钩子生成脑图快照 base64,发送自定义事件 mindDestroy f. 收到 mindDestroy 事件以 base64 当作快照 g. 将 base64 上传到服务器,拿到 URL 后替换节点 snapshot 属性

文档内脑图, WORD 脑图扩展
https://wangxiang.website/posts/编辑器/tiptap-tutorial10/
作者
翔子
发布于
2024-03-02
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
翔子
前端开发工程师
公告
博客已从 VitePress 迁移到 Astro + Firefly 主题,223 篇文章全部保留。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
221
分类
9
标签
28
总字数
411,914
运行时长
0
最后活动
0 天前

文章目录