vue3使用jodit富文本编辑器,自定义各项配置及组件封装

2023-10-27


本文使用时的版本:

"vue": "^3.2.36""jodit": "^3.24.7"

Jodit 是国外编写的一个功能强大的富文本编辑器,有常规版本和PRO版本,PRO版本功能更全,但需要付费,常规版本也已够用,目前官网没有提供中文文档。
当我们在使用时,会遇到一些问题,比如在设置了编辑器的语言版本为中文后,仍有部分还是英文显示,需要如何修改;还有如何将字体设置为一些常用中文字体;如何设置图片文件上传等等;
如果是在vue2中使用还需要去修改源码,则比较繁琐,具体实现方式可参考我之前发布的文章: vue2.x使用jodit富文本编辑器,并配置自定义字体和中文,本文主要针对于vue3(组合式)中的使用。
在vue3中就比较方便了,不用修改源码,全部可使用配置参数去设置,参数配置项多达159个,全部的配置项可参阅Jodit官网的config,这里列举一些常用项,全部的配置代码放在组件封装一节展示。

常用配置

设置中文

let config = {
 language: "zh_cn",
 i18n: {
   //将语言版本设置为中文后仍然还有部分显示的英文改为中文,左面的key为页面上显示的英文,value则是需要对应显示的中文,目前支持19种语言
    zh_cn: {//简体中文
      top: "上",
      right: "右",
      bottom: "下",
      left: "左",
      Title: "标题",
      Link: "链接",
      "Line height": "行高",
      Alternative: "描述",
      "Alternative text": "描述",
      "Lower Alpha": "小写英文字母",
      "Lower Greek": "小写希腊字母",
      "Lower Roman": "小写罗马数字",
      "Upper Alpha": "大写英文字母",
      "Upper Roman": "大写罗马数字",
    },
    zh_tw:{//中文繁体
      Link:'鏈接'
     }
  },
}

修改前后对比:
在这里插入图片描述

字体设置

需要注意的是,所设置的字体需要设备上安装的有才能正常显示,不然没效果。

import { Jodit } from "jodit";
let config = {
   controls: {
    font: {
      list: Jodit.atom({
      //左侧key为电脑上对应字体的名称,右侧value是在编辑器字体下拉列表中展示的名称
        "Microsoft YaHei": "微软雅黑",
        KaiTi: "楷体",
        方正喵呜体: "方正喵呜体",
        "思源宋体 Heavy": "思源宋体",
        SimHei: "黑体",
        NSimSun: "新宋体",
        华文行楷: "华文行楷",
      }),
    },
   }
  }

CDN的引用

Jodit引用的是外网cdn,有的时候访问不上,这里更换的是七牛cdn,建议更换的插件版本要同原来一致。

let config = {
 sourceEditorCDNUrlsJS: [
    // "https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.2/ace.js",原cdn
    "https://cdn.staticfile.org/ace/1.4.2/ace.js",
  ],
  beautifyHTMLCDNUrlsJS: [
    "https://cdn.staticfile.org/js-beautify/1.14.4/beautifier.min.js",
    "https://cdn.staticfile.org/js-beautify/1.14.4/beautify-html.min.js",
  ],
}

图片上传

如果不配置,只能使用url链接,不能上传本地图片。

let config = {
    uploader: {
      url: "/api/uploads",//上传地址
      isSuccess(res) {
        return res;
      },
      defaultHandlerSuccess(data) {
      //此处参数的值默认是接口返回的data值
        console.log("defaultHandlerSuccess", data);
        data.forEach((item) => {
        this.s.insertImage(item.url); //将图片插入编辑器中,不可省略
        });
     },
      defaultHandlerError(err) {
        console.log("defaultHandlerError", err);
        this.jodit.events.fire("errorMessage", err);
      },
      error(err) {
        console.log("error", err);
        this.jodit.events.fire("errorMessage", "文件上传失败");
    },
  },
}

对编辑器中生成的元素添加默认属性

比如 引用功能,元素标签是 blockquote,Jodit中生成的引用板块不明显,并未做具体的样式设置。

let config = {
   createAttributes: {
    blockquote: {//可以设置style,也可以设置class
      style: `
      display: block;
      padding: 16px;
      margin: 0 0 24px;
      border-left: 8px solid #dddfe4;
      background: #eef0f4;
      color: rgba(0, 0, 0, 0.5);
      overflow: auto;
      word-break: break-word !important;`,
      class:'blockquote-box'//在css中编写类名对应的样式
    },
  },
}

引用板块设置前后对比:
在这里插入图片描述

组件封装

Jodit v3版本的封装比较简单,这里就不一一阐述了,新建JoditEditor.vue,组件代码如下:

<template>
  <textarea id="editorRef" ref="editorRef" name="editor"></textarea>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from "vue";
import "jodit/build/jodit.min.css";
import { Jodit } from "jodit";

let editorRef = ref(null);
const props = defineProps({
  modelValue: String,
  config: { type: Object, default: () => ({}) },
});
const emit = defineEmits(["update:modelValue"]);

let editorInstance; //创建示例

let config = {
  theme: "default", //主题:默认default,暗色dark
  placeholder: "请输入内容...",
  zIndex: 10,
  language: "zh_cn",
  width: "100%",
  height: "100%",
  minHeight: 400,
  saveModeInCookie: false,
  toolbarSticky: false, //工具栏设置sticky
  statusbar: false, //底部状态栏(左:html元素;右:单词数,字符数统计)
  image: {
    //图片相关配置
    editSrc: false,
    editStyle: false,
    useImageEditor: false,
  },
  link: {
    noFollowCheckbox: false,
    modeClassName: "",
  },
  i18n: {
    zh_cn: {
      top: "上",
      right: "右",
      bottom: "下",
      left: "左",
      Title: "标题",
      Link: "链接",
      "Line height": "行高",
      Alternative: "描述",
      "Alternative text": "描述",
      "Lower Alpha": "小写英文字母",
      "Lower Greek": "小写希腊字母",
      "Lower Roman": "小写罗马数字",
      "Upper Alpha": "大写英文字母",
      "Upper Roman": "大写罗马数字",
    },
  },
  createAttributes: {
    blockquote: {
      style: `
      display: block;
      padding: 16px;
      margin: 0 0 24px;
      border-left: 8px solid #dddfe4;
      background: #eef0f4;
      color: rgba(0, 0, 0, 0.5);
      overflow: auto;
      word-break: break-word !important;`,
      class: "blockquote-box", //在css中编写类名对应的样式
    },
  },
  sourceEditorCDNUrlsJS: [
    // "https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.2/ace.js",
    "https://cdn.staticfile.org/ace/1.4.2/ace.js",
  ],
  beautifyHTMLCDNUrlsJS: [
    "https://cdn.staticfile.org/js-beautify/1.14.4/beautifier.min.js",
    "https://cdn.staticfile.org/js-beautify/1.14.4/beautify-html.min.js",
  ],

  //disablePlugins: "stat", //要禁用的插件,以逗号分割。stat是底部字符数与单词数统计
  buttons:
    "source,bold,italic,underline,strikethrough,eraser,superscript,subscript,ul,ol,indent,outdent,left,font,fontsize,paragraph,brush,lineHeight,image,file,video,copyformat,selectall,hr,table,link,symbols,undo,redo,fullsize,preview",
  controls: {
    font: {
      list: Jodit.atom({
        "Microsoft YaHei": "微软雅黑",
        KaiTi: "楷体",
        方正喵呜体: "方正喵呜体",
        "思源宋体 Heavy": "思源宋体",
        SimHei: "黑体",
        NSimSun: "新宋体",
        华文行楷: "华文行楷",
      }),
    },
  },
  uploader: {
    url: "/api/uploads", //上传地址
    isSuccess(res) {
      return res;
    },
    defaultHandlerSuccess(data) {
      //此处参数的值默认是接口返回的data值
      console.log("defaultHandlerSuccess", data);
      data.forEach((item) => {
        this.s.insertImage(item.url); //将图片插入编辑器中,不可省略
      });
    },
    defaultHandlerError(err) {
      console.log("defaultHandlerError", err);
      this.jodit.events.fire("errorMessage", err);
    },
    error(err) {
      console.log("error", err);
      this.jodit.events.fire("errorMessage", "文件上传失败");
    },
  },
};
onMounted(() => {
  editorInstance = Jodit.make("#editorRef", { ...config, ...props.config }); //合并组件传入的配置项并创建实例
  editorInstance.value = props.modelValue;
  editorInstance.events.on("change", (newValue) => {
    emit("update:modelValue", newValue);
  });
});
onBeforeUnmount(() => {
  editorInstance.destruct(); //组件销毁
  editorInstance = null;
});
watch(
  () => props.modelValue,
  (newValue) => {
    if (editorInstance.value !== newValue) {
      editorInstance.value = newValue;
    }
  }
);
</script>

<style lang="less">
.jodit-checkbox,
.jodit-ui-checkbox__input {
  appearance: checkbox;
  -webkit-appearance: checkbox;
}
.jodit .jodit-input {
  color: #666;
}
.jodit-ui-button_variant_primary {
  background-color: var(--themeColor);
}
.jodit-ui-button_variant_primary:hover:not([disabled]) {
  background-color: var(--themeColor-hover);
}
// .jodit-container {
// blockquote-box {
//   display: block;
//   padding: 16px;
//   margin: 0 0 24px;
//   border-left: 8px solid #dddfe4;
//   background: #eef0f4;
//   color: rgba(0, 0, 0, 0.5);
//   overflow: auto;
//   word-break: break-word !important;
// }
// }
.jodit-workplace {
  ol,
  ul,
  li {
    list-style-position: inside;
  }
}
</style>

使用封装后的组件:

<template>
  <div class="editor2">
    <h3 class="title">jodit编辑器示例</h3>
    <jodit-editor v-model="content" :config="config"></jodit-editor>
  </div>
</template>

<script setup>
import { ref } from "vue";
import JoditEditor from "../components/JoditEditor.vue";
let content = ref("");
//配置项
let config = {
  theme: "default", //主题模式 还可以设置为dark
  height: 500,
};
setTimeout(() => {
  content.value = "改变编辑器的内容";
}, 2000);
</script>

<style lang="less" scoped>
.editor2 {
  padding: 10px;
}
.title {
  text-align: center;
  color: var(--themeColor);
  font-size: 20px;
  font-family: "思源宋体";
}
</style>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3使用jodit富文本编辑器,自定义各项配置及组件封装 的相关文章

  • 从 Internet Explorer 打印时的默认文件名

    使用 pdf 打印机打印网页 将页面另存为 pdf 时 Chrome 和 Firefox 都使用该页面
  • 在 onclick 事件上请求麦克风

    有一天 我偶然发现了这个 Javascript 录音机的例子 http webaudiodemos appspot com AudioRecorder index html http webaudiodemos appspot com Au
  • 需要使用 iFrame API 隐藏 YouTube 品牌

    我正在使用 YouTube iFrame API 在我的自定义播放器 javascript 播放器 中加载视频 我需要隐藏 Youtube 品牌 但是在 iOS 设备上 它显示带有以下参数的徽标 playerVars fs 1 autopl
  • Chrome 扩展程序可以相互通信吗?

    我正在编写一个Chrome扩展程序 并且想要实现一个接口或api 以便我将来制作的其他扩展程序可以使用它 最终的效果可能如下 分机 B 呼叫extensionA someMethod someParameters 并向分机A发送一些数据 分
  • 如何在 mongodb 聚合管道中使用 Javascript 对象?

    我有一个 JS 对象norm我想在 mongo 聚合管道中使用它 如下所示 var norm 1 1 2 1 16 3 1 413 4 1 622 5 1 6 6 1 753 7 3 001 8 2 818 9 3 291 10 2 824
  • 有什么方法可以复制 div 的渲染 HTML 吗?

    我正在开发电子邮件签名生成器 我想通过按按钮复制最终签名 而不是手动选择签名并将其复制到剪贴板 这意味着我需要它们的图像 文本和样式 我尝试了几种变体 包括 w3schools 的变体 但没有成功 其中一些只是复制文本 但没有样式 例子 h
  • jQuery 可以操作插入的元素吗?

    我是 jQuery 的新手 我认为 jQuery 可以操作由代码添加的元素是合理的 但我发现现在还不能 function addVideo click function publisher append div div
  • Dialogflow Fulfillment Webhook 调用失败

    I am new to dialogflow fulfillment and I am trying to retrieve news from news API based on user questions I followed doc
  • Chrome 开发工具命中代码但未命中断点

    我在 chrome 开发工具上启用了断点 并且在一行上有一个断点 我知道 chrome 正在运行 因为我将断点放在具有以下语句的行上 alert why is this not breaking 如果我在本地主机中找到该文件 则断点有效 断
  • 角度垫排序不适用于带点表示法的 matColumnDef

    我正在尝试按列对表进行排序 当我必须过滤另一个结果中的结果时 就会出现问题 我尝试通过括号表示法和点表示法访问该属性 但没有给出结果 还将最终节点放置在 matColumnDef 中 但失败 因为有 2 列同名 table table
  • 仅在 Chrome 上我收到此错误:Uncaught TypeError: Illegal constructor [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 当我在 Chrome 上加载 jQuery 时 我会收到此错误 Uncaught TypeError Illegal constr
  • 如何设置必须输入特定数字的字段?

    我想知道如何创建一个需要输入特定数字或文本的字段 例如 激活码 以及在输入的确认答案的情况下移动到 网页 并且在未确认的情况下移动到 另一页面 的按钮 使用必需的属性
  • 自调用函数未定义

    如果我声明一个函数文字 var x function alert hi console log x returns the function code However var x function alert hi console log
  • D3 向对象添加超链接?

    我正在尝试制作 D3 图 它将代表我网站的菜单 我尝试按照此处的其他指南添加超链接 但它们都不起作用 每个对象都会有一个不同的 URL 指向 主页 关于 联系方式等 如果添加超链接 我可以拖动对象吗 这意味着如果我按住单击 如果我单击该对象
  • AngularStrap 工具提示禁用我的自定义指令

    我正在尝试让 bs tooltip AngularStrap 指令与我自己的名为 checkStrength 的自定义指令一起使用 该指令检查密码的强度 单独使用这些指令中的任何一个时 它们都可以正常工作 但不能一起工作 This http
  • 在 Android Chrome 中隐藏 HTML5 音频/视频通知

    我的网络应用程序上有一个 HTML5 音频元素 在某些时候 我使用以下代码以编程方式停止播放 audioElement pause audioElement currentTime 0 播放音频时 我的 Android 设备 使用 Goog
  • for循环中需要声明变量吗?

    有什么区别 for var i 0 i lt 5 i for i 0 i lt 5 i 是否有必要包含 var 关键字 我知道 var 关键字会影响变量范围 但我无法理解是否有必要在 for 循环中包含该关键字 在第二个示例中 您的变量是全
  • 将两个数字相加将它们连接起来而不是计算总和

    我将两个数字相加 但没有得到正确的值 例如 做1 2返回 12 而不是 3 我在这段代码中做错了什么 function myFunction var y document getElementById txt1 value var z do
  • 如何为 jQuery 插件设置私有变量?

    我想创建一个简单的插件 它使用元素的文本作为默认值 或者您可以在调用插件时设置此值 但是 如果我不设置该值 并为多个元素调用插件 则默认值会成倍增加 function fn reText function options var setti
  • 如何获取符号名称(文字)?

    以下情况 var myVehicle brand Tesla var isMoving Symbol var currentStatus Symbol myVehicle isMoving true myVehicle currentSta

随机推荐