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


本文使用时的版本:

"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>

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值