首页  >  问答  >  正文

传递数据给TipTap中的自定义Vue扩展的方法

我正在尝试将数据传递到在 tiptap 编辑器 内呈现的自定义 vue 组件。我可以传递 default 属性,但为其分配反应值似乎不起作用。

这是 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)
    },
})

editor 组件的 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) => {
    // Triggered upon 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>

srcdefault 可以通过,但是当我尝试分配一个响应对象(在安装 editor 组件后创建的)时,它最终会变成 undefined

这有效:

src: {
    default: '123'
}

但这不是:

...

src: {
    default: state.src
}

...

const sendDataToExtension = async (editor, event) => {
    // triggered upon event

    ...

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

}

如何向挂载editor后创建的vue组件发送数据?

尝试:

editor.chain().focus().insertContent('<vue-component/>', {src: state.src}).run()

P粉957723124P粉957723124297 天前661

全部回复(1)我来回复

  • P粉334721359

    P粉3347213592023-12-27 00:43:54

    首先,我会建议创建一个专门构建的扩展,而不是像现在那样使用通用的 VueComponent。如果您基于该扩展进行更多扩展,您将有多个扩展竞争该标签。将您在扩展中设置的所有代码移动到实际扩展中,您可以设置任何您想要的标记名称。

    现在我认为问题出在这里:insertContent 看起来像这样:

    insertContent: (value: Content, options?: {
        parseOptions?: ParseOptions;
        updateSelection?: boolean;
    })
    

    内容声明为

    export declare type Content = HTMLContent | JSONContent | JSONContent[] | null;
    export declare type HTMLContent = string;
    export declare type JSONContent = {
        type?: string;
        attrs?: Record<string, any>;
        content?: JSONContent[];
        marks?: {
            type: string;
            attrs?: Record<string, any>;
            [key: string]: any;
        }[];
        text?: string;
        [key: string]: any;
    };
    

    在您的情况下,您必须将 src 属性添加到您的 html 字符串中,但是我建议您在您的情况下使用 JSONContent 类型:

    editor.chain().focus().insertContent({type: "vueComponent", attrs:{src: state.src}}).run()
    

    这里的类型是您设置的组件名称。

    希望这是有道理的,tiptap 上的文档也很好https:// /tiptap.dev/guide/custom-extensions/#attributes 如果您还有其他问题,请告诉我。

    回复
    0
  • 取消回复