Methods for passing data to custom Vue extensions in TipTap
P粉957723124
P粉957723124 2023-12-26 13:03:48
0
1
667

I'm trying to pass data to a custom vue component rendered inside the tiptap editor. I can pass the default attribute, but assigning it a reactive value doesn't seem to work.

This is tiptap-node-extension.js File:

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 The script setup part of the component:

<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>

and vue components :

<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>
The

default for src passes, but when I try to allocate a response object (created after installing the editor component) it ends up becoming Become undefined.

This works:

src: {
    default: '123'
}

But this is not:

...

src: {
    default: state.src
}

...

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

    ...

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

}

How to send data to the vue component created after mounting editor?

try:

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

P粉957723124
P粉957723124

reply all(1)
P粉334721359

First of all, I would recommend creating a purpose-built extension instead of using the generic VueComponent as you do now. If you build more extensions based on that extension, you will have multiple extensions competing for that tag. Move all the code you set in the extension into the actual extension and you can set any tag name you want.

Now I think the problem is here: insertContent It looks like this:

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

Content declared as

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;
};

In your case you have to add the src attribute to your html string, but I recommend you to use JSONContent Type in your case:

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

The type here is the component name you set.

Hope this makes sense and the documentation on tiptap is goodhttps:// /tiptap.dev/guide/custom-extensions/#attributes If you have any further questions please let me know.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!