• md-editor-v3拓展工具栏失效的问题


    因为最近在写一个项目,需要用到emoji表情,所以想着用md-editor-v3去拓展一下,官方其实也给了文档,但是恕我直言,官方文档没有一个完整的示例,全是片段,也没搜到关于拓展emoji的文章,导致我花了大量的时间解决bug。

    在官方文档首页的展示里面有emoji,所以我根据他的地址到了github
    在这里插入图片描述
    进入EmojiExtension下的index.vue,里面提供了以下代码:

    <template>
      <dropdown-toolbar title="emoji" :visible="state.visible" @on-change="onChange">
        <template #overlay>
          <div class="emoji-container">
            <ol class="emojis">
              <li
                v-for="(emoji, index) of emojis"
                :key="`emoji-${index}`"
                @click="emojiHandler(emoji)"
                v-text="emoji"
              >li>
            ol>
          div>
        template>
        <template #trigger>
          <svg class="md-icon" aria-hidden="true">
            <use xlink:href="#icon-emoji">use>
          svg>
        template>
      dropdown-toolbar>
    template>
    
    <script lang="ts" setup>
    import { reactive } from 'vue';
    import type { PropType } from 'vue';
    import { emojis } from './data';
    const props = defineProps({
      editorId: {
        type: String as PropType<string>,
        default: ''
      }
    });
    const emit = defineEmits(['onChange']);
    const state = reactive({
      visible: false
    });
    const emojiHandler = (emoji: string) => {
      // 获取输入框
      const textarea = document.querySelector(
        `#${props.editorId}-textarea`
      ) as HTMLTextAreaElement;
      // 获取选中的内容
      const selection = window.getSelection()?.toString();
      // 获取鼠标位置
      const endPoint = textarea.selectionStart;
      // 根据鼠标位置分割旧文本
      // 前半部分
      const prefixStr = textarea.value.substring(0, endPoint);
      // 后半部分
      const suffixStr = textarea.value.substring(endPoint + (selection?.length || 0));
      emit('onChange', `${prefixStr}${emoji}${suffixStr}`);
      setTimeout(() => {
        textarea.setSelectionRange(endPoint, endPoint + 1);
        textarea.focus();
      }, 0);
    };
    const onChange = (visible: boolean) => {
      state.visible = visible;
    };
    script>
    
    <script lang="ts">
    export default {
      name: 'EmojiExtension'
    };
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    这份代码本身是没有问题的,但是不完整,使用时记得在index.vue的同级目录下复制data.ts,里面是emoji表情,可以自由替换。

    有了这个代码还是用不了的,我们再去看文档,在DropdownToolbar的演示里,给出了这样一段代码:

    <template>
      <md-editor-v3 v-model="text">
        <template #defToolbars>
          <dropdown-toolbar
            title="emoji"
            :visible="data.emojiVisible"
            :on-change="emojiVisibleChanged"
          >
            <template #overlay>
              <div class="emoji-container">
                <ol class="emojis">
                  <li
                    v-for="(emoji, index) of emojis"
                    :key="`emoji-${index}`"
                    @click="emojiHandler(emoji)"
                    v-text="emoji"
                  >li>
                ol>
              div>
            template>
            <template #trigger>
              <svg class="md-icon" aria-hidden="true">
                <use xlink:href="#icon-emoji">use>
              svg>
            template>
          dropdown-toolbar>
        template>
      md-editor-v3>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    再通过其他组件介绍,我们知道github里的dropdown-toolbar外面要套一层