Maison  >  Questions et réponses  >  le corps du texte

Méthodes pour transmettre des données aux extensions Vue personnalisées dans TipTap

J'essaie de transmettre des données dans l'attribut tiptap 编辑器 内呈现的自定义 vue 组件。我可以传递 default, mais lui attribuer une valeur réactive ne semble pas fonctionner.

Voici tiptap-node-extension.js Fichier :

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

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

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

Ça marche :

src: {
    default: '123'
}

Mais ce n'est pas :

...

src: {
    default: state.src
}

...

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

    ...

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

}

Comment envoyer des données à la montureeditor后创建的vue组件 ?

Essayez :

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

P粉957723124P粉957723124297 Il y a quelques jours663

répondre à tous(1)je répondrai

  • P粉334721359

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

    Tout d'abord, je recommanderais de créer une extension spécialement conçue au lieu d'utiliser une extension générique VueComponent comme vous le faites actuellement. Si vous créez davantage d'extensions basées sur cette extension, plusieurs extensions seront en compétition pour cette étiquette. Déplacez tout le code que vous avez défini dans l'extension dans l'extension réelle et vous pouvez définir le nom de balise de votre choix.

    Maintenant, je pense que le problème est là : insertContent Cela ressemble à ceci :

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

    Contenu déclaré comme

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

    Dans votre cas, vous devez ajouter l'attribut src à votre chaîne html, mais je vous recommande d'utiliser JSONContent tapez dans votre cas :

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

    Le type ici est le nom du composant que vous avez défini.

    J'espère que cela a du sens et que la documentation sur tiptap est bonne aussihttps:// /tiptap.dev/guide/custom-extensions/#attributes Si vous avez d'autres questions, n'hésitez pas à me le faire savoir.

    répondre
    0
  • Annulerrépondre