"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: "新宋体",
华文行楷: "华文行楷",
}),
},
}
}
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>