You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向TipTap中的自定义Vue扩展传递挂载后生成的响应式数据?

向TipTap自定义Vue组件传递响应式数据失效问题解决

我在TipTap编辑器中渲染自定义Vue组件时,默认属性能正常传递,但使用编辑器挂载后创建的响应式值时,数据变成undefined,无法生效。

相关代码文件

tiptap-node-extension.js

import {Node, mergeAttributes} from '@tiptap/core'
import {VueNodeViewRenderer} from '@tiptap/vue-3'
import Component from '@/views/components/vue-component.vue'

export default Node.create({
    parseHTML() {
        return [{ tag: 'vue-component' }]
    },
    renderHTML({ HTMLAttributes }) {
        return ['vue-component', mergeAttributes(HTMLAttributes)]
    },
    addNodeView() {
        return VueNodeViewRenderer(Component)
    },
})

编辑器组件的script setup部分

<script setup>
import {useEditor, EditorContent, BubbleMenu} from '@tiptap/vue-3'
import StarterKit from '@tiptap/starter-kit'
import {Underline} from "@tiptap/extension-underline";
import {TextAlign} from "@tiptap/extension-text-align";
import {Link} from "@tiptap/extension-link";
import VueComponent from '@/js/tiptap-node-extension.js'


const editor = useEditor({
    extensions: [
        StarterKit,
        TextAlign.configure({ types: ['heading', 'paragraph'] }),
        Underline,
        Link,
        VueComponent.extend({
                name: 'vueComponent',
                group: 'block',
                draggable: true,
                addAttributes() {
                    return {
                        src: {
                            default: '123',
                        }
                    }
                },
            }
        ),
    ],
    content: props.modelValue,
    onUpdate: ({ editor }) => {
        emit('update:modelValue', editor.getHTML())
    },
    editable: props.locked ? false : store.admin
})

const sendDataToExtension = async (editor, event) => {
    // 触发事件时执行

    ...

    state.src = '123'
    editor.chain().focus().insertContent('<vue-component/>').run()
}
</script>

对应的Vue组件

<script setup>
import {NodeViewWrapper} from '@tiptap/vue-3'

const props = defineProps({
    node: {
        type: Object,
        required: true
    },
    updateAttributes: {
        type: Function,
        required: true,
    }
})

</script>


<template>
  <node-view-wrapper class="vue-component" data-drag-handle="">
    <p>{{ node.attrs.src }}</p>
  </node-view-wrapper>
</template>

问题现象

  • 当设置src的默认值为固定字符串default: '123'时,属性能正常传递到组件。
  • 若将默认值改为响应式对象的属性default: state.src,或尝试通过insertContent的第二个参数传递属性时,src最终变为undefined。

解决方案

方法1:插入组件时在HTML标签中直接携带属性

insertContent的第二个参数并非用于传递节点属性,正确的做法是直接在HTML字符串中写入属性:

const sendDataToExtension = async (editor, event) => {
    state.src = '123'
    editor.chain().focus().insertContent(`<vue-component src="${state.src}"/>`).run()
}

方法2:使用insertNode方法精准传递节点属性

相比插入HTML字符串,insertNode能更明确地控制节点类型和属性,避免解析问题:

const sendDataToExtension = async (editor, event) => {
    state.src = '123'
    editor.chain().focus().insertNode({
        type: 'vueComponent', // 对应扩展中定义的name字段
        attrs: {
            src: state.src
        }
    }).run()
}

关键注意事项

  • 不要将响应式值放在扩展的addAttributes.default中:扩展初始化(编辑器创建时)state可能未完成初始化,且后续响应式更新不会同步到默认值——因为addAttributes仅在扩展定义时执行一次。
  • 更新已插入组件的属性:若后续需要修改已渲染组件的src值,可使用组件接收的updateAttributes方法:
    // 在自定义Vue组件内触发更新
    props.updateAttributes({ src: '新的响应式值' })
    

内容的提问来源于stack exchange,提问作者Artur Müller Romanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 17:45:44