首页 > 其他分享 >vue3使用富文本编辑器wangEditor 5,增加自定义下拉框,并动态改变下拉框内容

vue3使用富文本编辑器wangEditor 5,增加自定义下拉框,并动态改变下拉框内容

时间:2023-12-02 15:11:06浏览次数:57  
标签:文本编辑 菜单 const 自定义 value dataName editor 下拉框

官方资料

效果展示

20231101-150658.gif

准备工作

这里按照 wangEditor 官网提供的 Vue3 Demo 操作就行,下面的内容可以直接跳过

安装

yarn add @wangeditor/editor
# 或者 npm install @wangeditor/editor --save

yarn add @wangeditor/editor-for-vue@next
# 或者 npm install @wangeditor/editor-for-vue@next --save

使用

模版

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

script

<script>
  import "@wangeditor/editor/dist/css/style.css"; // 引入 css

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

  export default {
    components: { Editor, Toolbar },
    setup() {
      // 编辑器实例,必须用 shallowRef
      const editorRef = shallowRef();

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

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

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

      // 组件销毁时,也及时销毁编辑器
      onBeforeUnmount(() => {
        const editor = editorRef.value;
        if (editor == null) return;
        editor.destroy();
      });

      const handleCreated = (editor) => {
        editorRef.value = editor; // 记录 editor 实例,重要!
      };

      return {
        editorRef,
        valueHtml,
        mode: "default", // 或 'simple'
        toolbarConfig,
        editorConfig,
        handleCreated,
      };
    },
  };
</script>

demo

到这里我们就有了一个默认的富文本编辑器 image.png

自定义扩展功能(下拉框)

主要是参考官网提供的 SelectMenu 这部分的文档

第一,定义菜单 class

import { IDomEditor, ISelectMenu } from "@wangeditor/editor";

class MySelectMenu implements ISelectMenu {
  // 自带的字段
  title: string;
  tag: string;
  width: number;
  // 自定义的字段
  defineTitle: object; //下拉框显示的名字
  dataName: string; //下拉框选项值对应editor实例中的字段名,通过editor[dataName]=[]设置值
  options: any;
  // 使用类时需要接受一个参数 dataName
  constructor(dataName: any) {
    this.title = "select";
    this.tag = "select";
    this.width = 60;
    this.dataName = dataName;
    this.defineTitle = {
      value: "title",
      text: "插入字段",
      styleForRenderMenuList: { display: "none" },
    };
  }
  // 下拉框的选项
  getOptions(editor) {
    // 这里我将下拉框选项的值存在了 editor 实例中,以便可以动态改变选项值
    const displayOptions = editor[this.dataName].data || [];
    this.options = [this.defineTitle, ...displayOptions];
    return this.options;
  }
  // 菜单是否需要激活(如选中加粗文本,“加粗”菜单会激活),用不到则返回 false
  isActive(editor: IDomEditor): boolean {
    return false;
  }
  // 获取菜单执行时的 value ,用不到则返回空 字符串或 false
  getValue(editor: IDomEditor): string | boolean {
    return "title"; // 为了不改变下拉框的标题,永远返回 'title'
  }
  // 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
  isDisabled(editor: IDomEditor): boolean {
    return false;
  }
  // 点击菜单时触发的函数
  exec(editor: IDomEditor, value: string | boolean) {
    // 向富文本中插入选中项
    editor.insertText(`value`);
  }
}

第二,注册菜单到 wangEditor

参考官网文档中的 注册菜单到 wangEditor

先根据菜单 class 来定义菜单配置

const menu1Conf = {
  key: "mySelect1", // 定义 menu key :要保证唯一、不重复(重要)
  factory() {
    return new MySelectMenu(); //就是上面我们定义的class
  },
};

然后,再把菜单注册到 wangEditor 。

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

Boot.registerMenu(menu1Conf);

第三,插入菜单到工具栏

参考官网文档中的 插入菜单到工具栏

不过我是在初始化的时候就配置了,没有再另外插入。在 toolbarConfig 中可以配置自己想要的菜单。

const toolbarConfig = {
  toolbarKeys: [
    "fontSize",
    "lineHeight",
    "|",
    "bold",
    "italic",
    "underline",
    "color",
    "|",
    "|",
    "justifyLeft",
    "justifyCenter",
    "justifyRight",
    "|",
    "indent",
    "delIndent",
    "mySelect1", //自己扩展的下拉框,不过要注意一定要注册后才能写入
  ],
};

最终代码

这里就自己定义的 MySelectMenu 这个类新建了一个 selectTest.ts 文件,其余的都一股脑的塞进 editorDemo.vue 文件中了。由于就增加一个自定义配置,所以很多地方就直接写死了...

selectTest.ts

import { IDomEditor, ISelectMenu } from "@wangeditor/editor";

class MySelectMenu implements ISelectMenu {
  // 自带的字段
  title: string;
  tag: string;
  width: number;
  // 自定义的字段
  defineTitle: object;
  dataName: string; //下拉框选项值对应editor实例中的字段名,通过editor[dataName]=[]设置值
  options: any;
  constructor(dataName: any) {
    this.title = "select";
    this.tag = "select";
    this.width = 60;
    this.dataName = dataName;
    this.defineTitle = {
      value: "title",
      text: "插入字段",
      styleForRenderMenuList: { display: "none" },
    };
  }
  // 下拉框的选项
  getOptions(editor: any) {
    // 这里我将下拉框选项的值存在了 editor 实例中,以便可以动态改变选项值
    const displayOptions = editor[this.dataName].data || [];
    this.options = [this.defineTitle, ...displayOptions];
    return this.options; // 这里返回的就是显示在下拉框选项上的值
  }
  // 菜单是否需要激活(如选中加粗文本,“加粗”菜单会激活),用不到则返回 false
  isActive(editor: IDomEditor): boolean {
    return false;
  }
  // 获取菜单执行时的 value ,用不到则返回空 字符串或 false
  getValue(editor: IDomEditor): string | boolean {
    return "title"; // 为了不改变下拉框的标题,永远返回 'title'
  }
  // 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
  isDisabled(editor: IDomEditor): boolean {
    return false;
  }
  // 点击菜单时触发的函数
  exec(editor: IDomEditor, value: string | boolean) {
    // 向富文本中插入选中项
    editor.insertText(`${value}`);
  }
}

export default MySelectMenu;

editorDemo.vue

<template>
  <div class="editorDemo">
    <div style="border: 1px solid #ccc; width: 800px">
      <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        :mode="mode"
      />
      <Editor
        style="height: 400px; overflow-y: hidden"
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        :mode="mode"
        @onCreated="handleCreated"
      />
    </div>
  </div>

  <a-space wrap style="margin-top: 20px">
    <a-button type="primary" @click="updateSelectOptionData(0)">点我</a-button>
    <a-button type="primary" @click="updateSelectOptionData(1)"
      >点我!</a-button
    >
    <a-button type="primary" @click="updateSelectOptionData(2)"
      >点我啊!</a-button
    >
  </a-space>
</template>

<script>
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { onBeforeUnmount, ref, shallowRef, onMounted } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { Boot } from "@wangeditor/editor";
import MySelectMenu from "@/editor/selectTest";

export default {
  components: { Editor, Toolbar },
  setup() {
    // 编辑器实例,必须用 shallowRef
    const editorRef = shallowRef();

    // 内容 HTML
    const valueHtml = ref("");

    // --------注册自定义扩展菜单,因为只有一个,我直接写死了---------------
    const selectOption = ref({
      key: "mySelect1",
      dataName: "selectData",
      data: [
        { value: "北京", text: "北京" },
        { value: "上海", text: "上海" },
        { value: "深圳", text: "深圳" },
      ],
    });
    const menu1Conf = {
      key: selectOption.value.key, // 定义 menu key :要保证唯一、不重复(重要)
      factory() {
        return new MySelectMenu(selectOption.value.dataName);
      },
    };
    Boot.registerMenu(menu1Conf);
    // ----------------------------------------------------------------

    //自定义工具栏的菜单配置
    const toolbarConfig = {
      toolbarKeys: [
        "fontSize",
        "lineHeight",
        "|",
        "bold",
        "italic",
        "underline",
        "color",
        "|",
        "|",
        "justifyLeft",
        "justifyCenter",
        "justifyRight",
        "|",
        "indent",
        "delIndent",
        "mySelect1",
      ],
    };
    const editorConfig = { placeholder: "请输入内容..." };

    // 组件销毁时,也及时销毁编辑器
    onBeforeUnmount(() => {
      const editor = editorRef.value;
      if (editor == null) return;
      editor.destroy();
    });

    const handleCreated = (editor) => {
      editorRef.value = editor; // 记录 editor 实例,重要!
      // 我将下拉框选项的值保存在了 editor实例 身上
      editorRef.value[selectOption.value.dataName] = {
        data: selectOption.value.data,
      };
    };

    const dataTest = [
      [
        { value: "北京", text: "北京" },
        { value: "上海", text: "上海" },
        { value: "深圳", text: "深圳" },
      ],
      [
        { value: "汽车", text: "汽车" },
        { value: "大汽车", text: "大汽车" },
        { value: "超级大汽车", text: "超级大汽车" },
      ],
      [
        { value: "火车", text: "火车" },
        { value: "上海", text: "上海" },
        { value: "飞机", text: "飞机" },
      ],
    ];

    const updateSelectOptionData = (index) => {
      selectOption.value.data = dataTest[index];
      if (editorRef.value == null) return;
      // 主要就是更新 实例 中存的值
      editorRef.value[selectOption.value.dataName] = {
        data: selectOption.value.data,
      };
    };

    return {
      editorRef,
      valueHtml,
      mode: "default", // 或 'simple'
      toolbarConfig,
      editorConfig,
      handleCreated,
      updateSelectOptionData,
    };
  },
};
</script>
<style scoped>
.editorDemo {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

标签:文本编辑,菜单,const,自定义,value,dataName,editor,下拉框
From: https://www.cnblogs.com/wp-leonard/p/17871630.html

相关文章

  • SpringBoot自定义注解导出Excel
    先定义一个注解importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)public@interfaceExcelHander{Stringvalue()default"";StringlinkFiled()default"";Cel......
  • 在Unity中模块化管理自定义功能和资源
    之前在做Unity项目时,有时会遇到多个项目共用同一部分代码或资源的情况。而当被共用的部分需要更新的时候,手动复制替换非常麻烦,并且可能会有遗漏。对于这个问题,一个很好的解决办法是将可复用的文件打包为自定义包(CustomPackage),使用git等版本控制工具来管理每个包的内容。什么是Pa......
  • 1、自定义上传组件实现动态指定action
    1、增加ynamicAction:String2、修改constuploadImgUrl=ref(props.dynamicAction||import.meta.env.VITE_APP_BASE_API+"/common/upload");//上传的图片服务器地址<el-uploadmultiple:action="uploadImgUrl"3、父组件<el-form-itemlab......
  • Golang中如何自定义时间类型进行xml、json的序列化/反序列化
    在日常开发工作中,我们进行会遇到将struct序列化json字符串以及将json字符串反序列化为struct的场景,大家也对此十分熟悉。最近工作中,遇到了需要将struct序列化xml字符串以及将xml字符串反序列化为struct的场景,对于普通类型的字段,比如int、string等类型,直接......
  • 自定义bib文件
    一、使用在使用word编写论文时,需要使用参考论文格式,此时可以使用bib生成指定的格式,在放入文中进行使用。latex自带了一种bib参考格式的指令:latexmakebst通过上面的指令可以通过选项进行操作生成一个dbj文件。再通过对dbj文件的内容进行修改,就可以到一个目标的bst文件。但是......
  • vue关于自定义指令
    私有自定义指令(在与data()同级结构中进行配置)//私有自定义指令的节点directives:{//定义名为color的指令,指向一个配置对象color:{//当指令第一次被绑到元素上的时候,会立即触发bind函数,只会调用一次//形参中的el表示当前指令所绑定到的那个d......
  • uniapp使用微信jssdk自定义分享
    前言提示:本文记录的是使用uniapp开发的H5+APP项目,H5端使用微信自定义分享功能,文中有关APP的兼容,如果不需要兼容APP的可以忽略一、引入首先安装jweixin-module包npminstalljweixin-module--save二、封装工具方法为了方便使用,新建一个wechat.js文件://#ifdefH5impo......
  • 关于自定义R类-前后端数据交互协议
    关于自定义R类-前后端数据交互协议前言这是我在学习前后端分离开发时遇到的一种前后端数据交互思想时的笔记记录,以便日后遗忘查阅;目录目录关于自定义R类-前后端数据交互协议前言目录一、什么是前后端数据交互协议二、如何自定义一个结果类①思考R类要包含哪些基础属性②设......
  • tita升级|考核流程支持自定义配置
    升级详情:“推荐你关注一下TitaOKR“1.考核流程中新增指标制定与确认流程Q1:在哪新增?小T:在考核模板的考核流程设置中,指标制定与指标确认流程节点有两种添加方式:1)考核模板中新增固定流程三,固定流程三为考核流程为“指标制定+指标确认+执行期+员工自评+同事评价+上级评价+绩效校......
  • WPS Excel如何设置下拉框
    Excel作为一款强大的电子表格软件,提供了各种功能来帮助用户更便捷地管理和分析数据。其中,设置下拉框是一种常用的技巧,可以简化数据输入过程,减少错误。下面我们将介绍如何在Excel中设置下拉框。第一步:打开一个需要设置下拉选项的wps表格。第二步:选中单元格,在菜单栏“数据”中,单......