文档内脑图, WORD 脑图扩展
正在加载今日诗词....
2024-03-01

需求: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 属性

京ICP备2022027737号
Copyright © 2022 - present @wangxiang

  • ☀️
  • 🌑