Skip to content

编辑器自定义按钮 button

效果

流程

注意

  1. 引入 boot import { Boot } from "@wangeditor/editor";

  2. 工具栏配置

  3. 自定义按钮(类和实例化)

  4. 注册自定义按钮

代码

vue
<template>
  <div style="border: 1px solid #ccc">
    <Toolbar
      style="border-bottom: 1px solid #ccc"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    <Editor
      style="height: 500px; overflow-y: hidden"
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
    />
  </div>
  <div class="modal" v-show="modalflag">遮罩层</div>
  <button @click="getcontent">提交</button>
</template>

<script setup lang="ts">
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { onBeforeUnmount, ref, shallowRef, onMounted } from "vue";

import { Editor, Toolbar } from "@wangeditor/editor-for-vue";

// 1. 引入boot

import { Boot } from "@wangeditor/editor";

// 扩展

const modalflag = ref(false);

// 编辑器实例,必须用shallowRef包裹

const editorRef = shallowRef();

// 内容HTML

const valueHtml = ref("<p>hello</p>");

// 编辑器模式

const mode = ref("default"); // simple或者default;

// 模拟ajax异步获取数据内容

onMounted(() => {
  setTimeout(() => {
    valueHtml.value = "<p>模拟 Ajax 异步设置内容</p>";
  }, 1500);
});

// (2) 工具栏配置

const toolbarConfig = {
  insertKeys: {
    index: 0, // 插入的位置,基于当前的 toolbarKeys
    keys: ["myMenu"],
  },
};

// 编辑器配置

const editorConfig = { placeholder: "请输入内容..." };

// 组件销毁的时候,也即时 销毁编辑器

onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});

// 编辑器示例

const handleCreated = (editor: any) => {
  editorRef.value = editor; // 记录editor实例
};

// 获取到编辑器内容

const getcontent = () => {
  window.alert(valueHtml.value);
};

// (3) 自定义按钮
class MyMenu {
  public title: string = "";

  public tag: string = "";

  public iconSvg: string = "";

  constructor() {
    // 自定义菜单标题

    this.title = "自定义按钮";

    // 类型

    this.tag = "button";

    // 自定义菜单图标

    this.iconSvg =
      '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" t="1687315735883" class="icon" viewBox="0 0 1024 1024" version="1.1" p-id="13367" width="16" height="16" style="color:white;"><path stroke="#ff0000" fill="#ff0000" d="M890.88 63.488q28.672 0 52.736 10.752t41.984 29.184 28.16 43.52 10.24 53.76l0 620.544q0 28.672-10.24 53.76t-28.16 43.52-41.984 29.184-52.736 10.752l-689.152 0q-28.672 0-53.76-10.752t-43.52-29.184-29.184-43.52-10.752-53.76l0-620.544q0-28.672 10.752-53.76t29.184-43.52 43.52-29.184 53.76-10.752l689.152 0zM256 254.976q9.216 0 27.648 0.512t43.008 0.512l52.224 0 55.296 0q64.512 0 141.312-1.024l0-63.488-126.976 0 0-64.512-64.512 0 0 64.512-128 0 0 63.488zM377.856 360.448q-8.192-15.36-15.36-29.696-6.144-12.288-12.288-25.088t-9.216-20.992l-58.368 21.504 32.768 76.8zM254.976 756.736l101.376-143.36-66.56-26.624-98.304 145.408zM448.512 574.464l126.976 0 0-62.464-45.056 0-81.92 0 0-64.512q23.552 0 46.08 0.512t40.96 0.512l40.96 0 0-63.488-66.56 0q-19.456 0-40.96-1.024l68.608-65.536-68.608-32.768-20.48 98.304-257.024 0 0 63.488 35.84 0 47.104 0 53.248 0 56.32 0 0 64.512-128 0 0 62.464 40.96 0q18.432 0 40.96 0.512t46.08-0.512l0 129.024q0 16.384-2.048 27.136t-10.24 15.36-25.088 4.608-47.616-5.12q25.6 31.744 27.648 71.68 13.312-2.048 34.304-1.024t40.448-1.536 33.28-12.8 13.824-34.816l0-192.512zM568.32 685.056q-16.384-19.456-29.696-37.888-11.264-15.36-23.552-30.208t-18.432-23.04l-46.08 30.72 64.512 98.304zM896 379.904q-20.48-1.024-53.248-0.512t-63.488 1.536q-36.864 1.024-75.776 3.072l0-129.024q49.152 0 85.504-4.608t59.904-9.728q27.648-6.144 46.08-14.336-18.432-27.648-29.696-46.08-5.12-8.192-9.728-15.36t-7.68-11.264-3.584-4.608 1.536 4.608q-21.504 16.384-57.344 24.064t-69.632 10.752-57.344 3.072-21.504 0q1.024 16.384 1.536 44.032t0 77.824-1.024 129.024-0.512 196.608q0 13.312-3.072 33.28t-10.24 39.936-19.968 35.328-31.232 19.456q12.288 3.072 21.504 11.776t16.896 18.432 13.824 19.456 12.288 14.848q12.288-18.432 23.552-42.496t20.48-50.176 14.336-52.224 5.12-47.616l0-40.96 0-43.008 0-47.104 0-60.416 64.512 0 0 384 63.488 0 0-384q23.552 1.024 35.328 0.512t29.184 3.584l0-71.68z" p-id="13368"></path></svg>';
  }

  // 获取菜单执行时的value,用不到则返回空,字符串或者false

  getValue(editor: any) {
    console.log(editor);
    return "自定义按钮";
  }

  // 菜单是否需要激活(如选中加粗文本,"加粗"菜单会激活) 用不到则返回 false

  isActive(editor: any) {
    return false; // or true
  }

  // 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false

  isDisabled(editor: any) {
    return false; // or true
  }

  // 点击菜单出发的函数
  exec(editor: any, value: any) {
    // 插入文本
    // editor.insertText(value); // value 即 this.getValue(editor) 的返回值
    // 插入对话框
    // modalflag.value = true;
    // 插入节点
    const resulttext =
      '<p><img src="https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/live/color_avatar/2.png"></p>';
    editor.dangerouslyInsertHtml(resulttext);
  }
}

// 注册自定义菜单

const myMenuConf = {
  key: "myMenu",
  factory() {
    return new MyMenu();
  },
};

Boot.registerMenu(myMenuConf);
</script>

<style scoped lang="scss">
.modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 9999;
}
</style>