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

Vue3+Composition API+TS下TipTap交互组件传参问题求助

解决Vue3 Script Setup+TypeScript中TipTap节点视图Props未定义及初始值传递问题

问题分析

你的代码核心问题有两个:

  • Script Setup中未正确定义TipTap NodeView的Props类型,导致TS无法识别node和updateAttributes,运行时出现props未定义错误
  • 扩展的parseHTML/renderHTML使用了自定义标签(DevPropTest),浏览器无法解析,导致初始属性值无法正确传递到节点

解决方案

1. 修正Vue组件的Props定义(DevPropTest.vue)

导入TipTap提供的NodeViewProps类型,确保Props类型和TipTap传递的参数匹配:

<script setup lang="ts">
import { NodeViewWrapper, type NodeViewProps } from "@tiptap/vue-3";

// 使用TipTap提供的NodeViewProps类型定义组件Props
const props = defineProps<NodeViewProps>()

const increase = () => {
  props.updateAttributes({
    count: (props.node.attrs.count as number) + 1,
  })
}
</script>

<template>
  <node-view-wrapper class="DevPropTest">
    <span class="label">Vue Component</span>
    <div class="content">
      <button @click="increase">
        This button has been clicked {{ node.attrs.count }} times.
      </button>
    </div>
  </node-view-wrapper>
</template>

2. 修正TipTap扩展的HTML解析与渲染逻辑(DevPropTestExtension.ts)

改用真实HTML标签(如div)配合自定义属性,确保浏览器能正确解析:

import { mergeAttributes, Node } from '@tiptap/core'
import { VueNodeViewRenderer } from "@tiptap/vue-3";
import DevPropTest from "@/components/UI/Widgets/DevSemanticEditor/Parts/Media/DevPropTest.vue";

export default Node.create({
    name: 'devPropTest', // 建议用小写短横线命名,符合TipTap规范
    group: 'block',
    atom: true,
    draggable: true,

    addAttributes() {
        return {
            count: {
                default: 3,
                parseHTML: element => parseInt(element.getAttribute('count') || '3'),
                renderHTML: attributes => ({ count: attributes.count })
            }
        }
    },

    parseHTML() {
        // 匹配带自定义属性的div标签
        return [{
            tag: 'div[data-dev-prop-test]',
            getAttrs: element => ({
                count: (element as HTMLElement).getAttribute('count')
            })
        }]
    },

    renderHTML({ HTMLAttributes }) {
        // 渲染为带自定义属性的div标签
        return ['div', mergeAttributes(HTMLAttributes, { 'data-dev-prop-test': '' })];
    },

    addNodeView() {
        return VueNodeViewRenderer(DevPropTest);
    }
});

3. 修正编辑器初始内容

使用真实的HTML结构,匹配扩展的parseHTML规则:

import { reactive } from 'vue'
import { useEditor, StarterKit } from '@tiptap/vue-3'
import DevPropTestExtension from './DevPropTestExtension'

let editor = reactive(
    useEditor({
      content: `<div data-dev-prop-test count="3"></div>`,
      extensions: [
        StarterKit,
        DevPropTestExtension,
      ],
    })
)

关键说明

  • 必须使用TipTap提供的NodeViewProps类型定义组件Props,否则Script Setup的TS类型推断会失效,导致node和updateAttributes无法被识别
  • 避免使用自定义HTML标签,改用标准标签+自定义属性的方式,确保HTML解析和渲染正常
  • 在addAttributes中显式定义parseHTML和renderHTML逻辑,保证属性值在解析和渲染时正确转换

内容的提问来源于stack exchange,提问作者Stepan Berkunov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 07:00:30