基于"wangeditor": "^4.6.10"+ vue3+ vue-class-component 温馨提醒:其它项目插件肯定不一定全部存在,但是实现方案是这样的可以参考参考
先上效果:
实现代码
<template>
<div class="content">
<p name="editor" id="editor" ref="editor" style="z-index: -1"></p>
</div>
</template>
<script lang="ts">
import { reactive } from "vue";
import { Options, Vue } from "vue-class-component";
import EWangEditor from "wangeditor";
import { updateFile } from "@/https/apis";
@Options({
props: {
modelValue: String,//富文本插件绑定的值
isShowDetails: Boolean,//是否是显示详情,显示详情不可编辑
height:{
type: Number,
default: 300
}
},
emits: ["update:modelValue"],
})
export default class MyEditor extends Vue {
modelValue!: string;
isShowDetails!: boolean;
state = reactive<any>({});
editor: any;
height: number;
mounted() {
this.createEditor();
this.editor.txt.html(this.modelValue);//设置内容
if (this.isShowDetails) {
this.editor.disable();//禁用编辑器
}
}
createEditor() {
this.editor = new EWangEditor("#editor");
// this.editor.config.uploadImgShowBase64 = true;
this.editor.config.showLinkImg = false;
// 配置触发 onchange 的时间频率,默认为 200ms
this.editor.config.onchangeTimeout = 400;
this.editor.config.placeholder = "";//没有内容时的输入提示
this.editor.config.height = this.height;//设置编辑区域高度
// 如果插件绑定的值发生改变,触发这个函数执行
this.editor.config.onchange = (html) => {
this.state.editorContent = html;
this.$emit("update:modelValue", html);
};
this.editor.config.customAlert = (err) => {
console.log(err);
};//自定义 alert
//以下为新增
const menuItem = [
//工具栏里有哪些工具
"head", // 标题
"bold", // 粗体
"fontSize", //字号
"fontName", //字体
"italic", // 斜体
"underline", //下划线
"strikeThrough", //删除线
"indent", //缩进
"lineHeight", //行高
"foreColor", //文字颜色
"backColor", //文字背景颜色
"link", //链接,插入一个链接地址,如果填写了描述,则高亮显示描述。若没有,则高亮显示链接
"list", // 序列(有序列表、无序列表)
"todo", //待办事项
"justify", // 对齐方式
"quote", //引用
// "emoticon", //表情
"image", //插入图片
// "video", //插入视频
"table", //表格
"code", //代码
"splitLine", //分割线
"undo", //撤销
"redo", //恢复
];
this.editor.config.menus = [...menuItem]; /* 自定义显示哪些菜单和菜单的顺序 */
this.editor.config.colors = [
"#000000",
"#eeece0",
"#1c487f",
"#4d80bf",
]; /* 文字颜色、背景色可以选择哪些颜色? */
this.editor.config.fontNames = [
"黑体",
"仿宋",
"楷体",
"标楷体",
"华文仿宋",
"华文楷体",
"宋体",
"微软雅黑",
];/* 字体工具提供哪些字体? */
// 自定义上传图片
this.editor.config.customUploadImg = function (files, insert) {
// files 是 input 中选中的文件列表
// insert 是获取图片 url 后,插入到编辑器的方法
// 在这里进行一系列的校验
// const formData = new FormData();
// formData.append("file", files[0]);
// axios
// .post(
// "http://localhost:8080/itkb/square/article/uploadArticleImage",
// formData,
// {
// "Content-type": "multipart/form-data",
// }
// )
// .then(
// (res) => {
// // 上传成功后的处理
// // 上传代码返回结果之后,将图片插入到编辑器中
// insert(res.data);
// },
// (err) => {
// // 出现错误时的处理
// console.log("上传图片失败" + err.data);
// }
// );
updateFile(files[0]).then((res) => {
insert(process.env.VUE_APP_IMG_URL + res.data);
});
};
//创建编辑器
this.editor.create();
}
unmounted() {
this.editor = null;
}
}
</script>
<style scoped>
.content {
position: relative;
z-index: 100;
}
</style>
使用
import myEditor from "@/components/myEditor.vue"
<myEditor v-model:modelValue="state.formData.value2" :isShowDetails="isShowDetails"/>
功能拓展
现菜单是否展示,以及是否有边框,最小高度等拓展需求的封装
<template>
<div class="content">
<p
v-if="isHaveMenu"
name="editor1"
class="border"
id="editor1"
ref="editor1"
style="z-index: -1"
></p>
<p
name="editor2"
:class="isHaveBodyBorder ? 'border' : ''"
id="editor2"
ref="editor2"
:style="{ zIndex: -1,minHeight:'300px' }"
></p>
</div>
</template>
<script lang="ts">
import { reactive } from "vue";
import { Options, Vue } from "vue-class-component";
import EWangEditor from "wangeditor";
import { updateAnnex } from "@/https/notification-manager-apis"
@Options({
props: {
modelValue: String,//富文本插件绑定的值
isShowDetails: Boolean,//是否是显示详情,显示详情不可编辑
height: {
type: Number,
default: 300
},
isHaveMenu: {//是否有顶部菜单栏
type: Boolean,
default: true
},
isHaveBodyBorder: {//是否内容区域外边框
type: Boolean,
default: true
}
},
emits: ["update:modelValue"],
})
export default class MyEditor extends Vue {
modelValue!: string;
isShowDetails!: boolean;
isHaveMenu: boolean;
isHaveBodyBorder: boolean;
state = reactive<any>({});
editor: any;
height: number;
mounted() {
this.createEditor();
this.editor.txt.html(this.modelValue);//设置内容
if (this.isShowDetails) {
this.editor.disable();//禁用编辑器
}
}
createEditor() {
this.editor = new EWangEditor("#editor1", "#editor2");
// this.editor.config.uploadImgShowBase64 = true;
this.editor.config.showLinkImg = false;
// 配置触发 onchange 的时间频率,默认为 200ms
this.editor.config.onchangeTimeout = 400;
this.editor.config.placeholder = "";//没有内容时的输入提示
this.editor.config.height = this.height;//设置编辑区域高度
// 如果插件绑定的值发生改变,触发这个函数执行
this.editor.config.onchange = (html) => {
this.state.editorContent = html;
this.$emit("update:modelValue", html);
};
this.editor.config.customAlert = (err) => {
console.log(err);
};//自定义 alert
//以下为新增
const menuItem = [
//工具栏里有哪些工具
"head", // 标题
"bold", // 粗体
"fontSize", //字号
"fontName", //字体
"italic", // 斜体
"underline", //下划线
"strikeThrough", //删除线
"indent", //缩进
"lineHeight", //行高
"foreColor", //文字颜色
"backColor", //文字背景颜色
"link", //链接,插入一个链接地址,如果填写了描述,则高亮显示描述。若没有,则高亮显示链接
"list", // 序列(有序列表、无序列表)
"todo", //待办事项
"justify", // 对齐方式
"quote", //引用
// "emoticon", //表情
// "image", //插入图片
// "video", //插入视频
"table", //表格
"code", //代码
"splitLine", //分割线
"undo", //撤销
"redo", //恢复
];
this.editor.config.menus = [...menuItem]; /* 自定义显示哪些菜单和菜单的顺序 */
this.editor.config.colors = [
"#000000",
"#eeece0",
"#1c487f",
"#4d80bf",
]; /* 文字颜色、背景色可以选择哪些颜色? */
this.editor.config.fontNames = [
"黑体",
"仿宋",
"楷体",
"标楷体",
"华文仿宋",
"华文楷体",
"宋体",
"微软雅黑",
];/* 字体工具提供哪些字体? */
// 自定义上传图片
this.editor.config.customUploadImg = function(files, insert) {
// files 是 input 中选中的文件列表
// insert 是获取图片 url 后,插入到编辑器的方法
// 在这里进行一系列的校验
// const formData = new FormData();
// formData.append("file", files[0]);
// axios
// .post(
// "http://localhost:8080/itkb/square/article/uploadArticleImage",
// formData,
// {
// "Content-type": "multipart/form-data",
// }
// )
// .then(
// (res) => {
// // 上传成功后的处理
// // 上传代码返回结果之后,将图片插入到编辑器中
// insert(res.data);
// },
// (err) => {
// // 出现错误时的处理
// console.log("上传图片失败" + err.data);
// }
// );
updateAnnex(files[0]).then((res) => {
insert(process.env.VUE_APP_IMG_URL + res.data);
});
};
//创建编辑器
this.editor.create();
}
unmounted() {
this.editor = null;
}
}
</script>
<style scoped>
.content {
position: relative;
z-index: 100;
}
.border {
border: 1px solid #ccc;
}
</style>