微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

获取 tiptap-vuetify 以在 Vue Nuxt 应用程序中使用“提及”

如何解决获取 tiptap-vuetify 以在 Vue Nuxt 应用程序中使用“提及”

所以我的问题是我似乎无法在 vuetify-nuxt 项目中使用 tiptap 的“提及”功能

原始示例可在here

更多有用信息:

  • 来自tiptap github here

    的示例实现
  • 问了类似的问题但没有完全回答here

  • 在 vuetify 集成库中提出的类似问题 here

为此,我正在尝试结合文档示例。

我想在我尝试使用“tippy”时会出错,这是用于显示实际列出要从中选择的用户的弹出窗口的 css 库(在 @ 之后),但我不能似乎不明白真正的问题。

因此,当我键入 @ 时,keydown/up 事件侦听器正在运行,但提示似乎没有成功绑定弹出窗口(未显示),并出现以下错误

Editor.vue?6cd8:204 Uncaught TypeError: Cannot read property '0' of undefined
    at VueComponent.enterHandler (Editor.vue?6cd8:204)
    at onKeyDown (Editor.vue?6cd8:175)
    at Plugin.handleKeyDown (extensions.esm.js?f23d:788)
    at eval (index.es.js?f904:3298)
    at EditorView.someProp (index.es.js?f904:4766)
    at editHandlers.keydown (index.es.js?f904:3298)

这是我的tippy.js nuxt插件

import Vue from "vue";
import VueTippy,{ Tippycomponent } from "vue-tippy";

Vue.use(VueTippy,{
    interactive: true,theme: "light",animateFill: false,arrow: true,arrowType: "round",placement: "bottom",trigger: "click",// appendTo: () => document.getElementById("app")
});

Vue.component("tippy",Tippycomponent);

这是我试图在其中显示编辑器和建议/提及功能的组件:

<template>
  <div>
    <div class="popup">
      aaaa
    </div>
    <editor-menu-bar v-slot="{ commands }" :editor="editor">
      <div class="menubar">
        <v-btn class="menubar__button" @click="commands.mention({ id: 1,label: 'Fred Kühn' })">
          <v-icon left>@</v-icon>
          <span>Mention</span>
        </v-btn>
      </div>
    </editor-menu-bar>

    <tiptap-vuetify v-model="localValue" :extensions="extensions" :native-extensions="nativeExtensions" :toolbar-attributes="{ color: 'grey' }" @init="onInit" />
  </div>
</template>

<script>
// import the component and the necessary extensions
import {
  TiptapVuetify,heading,Bold,Italic,Strike,Underline,Code,CodeBlock,Image,Paragraph,BulletList,OrderedList,ListItem,Link,Blockquote,HardBreak,HorizontalRule,History,} from "tiptap-vuetify";

// TESTING
import { EditorMenuBar,Editor } from "tiptap";
import { Mention } from "tiptap-extensions";
import tippy,{ sticky } from "tippy.js";

export default {
  components: { TiptapVuetify,EditorMenuBar },props: {
    value: {
      type: String,default: "",},data: () => ({
    editor: null,extensions: null,nativeExtensions: null,// TESTING
    query: null,suggestionRange: null,filteredUsers: [],navigatedUserIndex: 0,insertMention: () => {},popup: null,}),computed: {
    localValue: {
      get() {
        return this.value;
      },set(value) {
        this.$emit("input",value);
      },// TESTING
    hasResults() {
      return this.filteredUsers.length;
    },showSuggestions() {
      return this.query || this.hasResults;
    },created() {
    this.extensions = [
      History,[
        heading,{
          options: {
            levels: [1,2,3],],];
    this.nativeExtensions = [
      // https://github.com/ueberdosis/tiptap/blob/main/examples/Components/Routes/Suggestions/index.vue
      new Mention({
        // a list of all suggested items
        items: async () => {
          await new Promise((resolve) => {
            setTimeout(resolve,500);
          });
          return [
            { id: 1,name: "sven Adlung" },{ id: 2,name: "Patrick Baber" },{ id: 3,name: "Nick Hirche" },{ id: 4,name: "Philip Isik" },{ id: 5,name: "Timo Isik" },{ id: 6,name: "Philipp Kühn" },{ id: 7,name: "Hans Pagel" },{ id: 8,name: "Sebastian Schrama" },];
        },// When @ is pressed,we enter here
        onEnter: ({ items,query,range,command,virtualNode }) => {
          this.query = query; // the field that the @ queries? currently empty
          this.filteredUsers = items;
          this.suggestionRange = range;

          this.renderPopup(virtualNode); // render popup - failing

          this.insertMention = command; // this is saved to be able to call it from within the popup
        },// probably when value after @ is changed
        onChange: ({ items,virtualNode }) => {
          this.query = query;
          this.filteredUsers = items;
          this.suggestionRange = range;
          this.navigatedUserIndex = 0;
          this.renderPopup(virtualNode);
        },// mention canceled
        onExit: () => {
          // reset all saved values
          this.query = null;
          this.filteredUsers = [];
          this.suggestionRange = null;
          this.navigatedUserIndex = 0;
          this.destroyPopup();
        },// any key down during mention typing
        onKeyDown: ({ event }) => {
          if (event.key === "ArrowUp") {
            this.upHandler();
            return true;
          }
          if (event.key === "ArrowDown") {
            this.downHandler();
            return true;
          }
          if (event.key === "Enter") {
            this.enterHandler();
            return true;
          }
          return false;
        },// there may be built-in filtering,not sure
        onFilter: async (items,query) => {
          await console.log("on filter");
        },];
  },methods: {
    // TESTING
    // navigate to the prevIoUs item
    // if it's the first item,navigate to the last one
    upHandler() {
      this.navigatedUserIndex =
        (this.navigatedUserIndex + this.filteredUsers.length - 1) %
        this.filteredUsers.length;
    },// navigate to the next item
    // if it's the last item,navigate to the first one
    downHandler() {
      this.navigatedUserIndex =
        (this.navigatedUserIndex + 1) % this.filteredUsers.length;
    },enterHandler() {
      const user = this.filteredUsers[this.navigatedUserIndex];
      if (user) {
        this.selectUser(user);
      }
    },// we have to replace our suggestion text with a mention
    // so it's important to pass also the position of your suggestion text
    selectUser(user) {
      this.insertMention({
        range: this.suggestionRange,attrs: {
          id: user.id,label: user.name,});
      this.editor.focus();
    },renderPopup(node) {
      if (this.popup) {
        return;
      }
      // ref: https://atomiks.github.io/tippyjs/v6/all-props/
      this.popup = tippy(".page",{
        getReferenceClientRect: node.getBoundingClientRect,// input location
        appendTo: () => document.body,// must be issue
        interactive: true,sticky: true,// make sure position of tippy is updated when content changes
        plugins: [sticky],content: this.$refs.suggestions,trigger: "mouseenter",// manual
        showOnCreate: true,theme: "dark",placement: "top-start",inertia: true,duration: [400,200],});
    },destroyPopup() {
      if (this.popup) {
        this.popup[0].destroy();
        this.popup = null;
      }
    },beforeDestroy() {
      this.destroyPopup();
    },/**
     * NOTE: destructure the editor!
     */
    onInit({ editor }) {
      this.editor = editor;
    },};
</script>

如何在上述设置中显示“建议”项?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。