1.安装 (vue2)
yarn add @wangeditor/editor
# 或者 npm install @wangeditor/editor --save
yarn add @wangeditor/editor-for-vue
# 或者 npm install @wangeditor/editor-for-vue --save
2. 使用 (可封装成子组件)
<template>
<div style="border: 1px solid #ccc">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:default-config="toolbarConfig"
:mode="mode"
/>
<Editor
v-model.trim="html"
style="height: 500px; overflow-y: hidden"
:default-config="editorConfig"
:mode="mode"
@onChange="onChange"
@onCreated="onCreated"
/>
</div>
</template>
<script>
import Vue from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { upload } from "@/api/guideCertificate/guideCertificateIndex";
import { getToken } from "@/utils/auth";
import { DomEditor } from '@wangeditor/editor'
const editorConfig = {
// JS 语法
MENU_CONF: {},
// 其他属性...
};
editorConfig.MENU_CONF["uploadImage"] = {
server: "/concatenation/dzznInfo/upload",
fieldName: "multipartFile",
// 自定义增加 http header
headers: {
Authorization: getToken(),
},
async customUpload(file, insertFn) {
// JS 语法
console.log(file);
const fileData = new FormData();
fileData.append("multipartFile", file);
upload(fileData).then((res) => {
insertFn(res.data.filePath, "", "");
});
// file 即选中的文件
// 自己实现上传,并得到图片 url alt href
// 最后插入图片
// insertFn(url, alt, href)
},
// 继续写其他配置...
// 【注意】不需要修改的不用写,wangEditor 会去 merge 当前其他配置
};
editorConfig.MENU_CONF["uploadVideo"] = {
server: "/concatenation/dzznInfo/upload",
fieldName: "multipartFile",
// 自定义增加 http header
headers: {
Authorization: getToken(),
},
async customUpload(file, insertFn) {
// JS 语法
console.log(file);
const fileData = new FormData();
fileData.append("multipartFile", file);
upload(fileData).then((res) => {
insertFn(res.data.filePath, "", "");
});
// file 即选中的文件
// 自己实现上传,并得到图片 url alt href
// 最后插入图片
// insertFn(url, alt, href)
},
// 继续写其他配置...
// 【注意】不需要修改的不用写,wangEditor 会去 merge 当前其他配置
};
export default Vue.extend({
components: { Editor, Toolbar },
props: {
value: {
type: [Number, String],
default: undefined,
},
},
data() {
return {
editor: null,
editorContent: null,
editorContents: null,
html: undefined,
toolbarConfig: {},
editorConfig,
mode: "default", // or 'simple'
};
},
mounted() {
// 模拟 ajax 请求,异步渲染编辑器
// setTimeout(() => {
// }, 1500)
},
watch: {
value(nl, ol) {
this.html = this.value;
// console.log(nl, ol, "====================");
this.onChange(this.editor);
},
},
beforeDestroy() {
const editor = this.editor;
if (editor == null) return;
editor.destroy(); // 组件销毁时,及时销毁编辑器
},
methods: {
onCreated(editor) {
this.editor = Object.seal(editor); // 一定要用 Object.seal() ,否则会报错
//
this.toolbarConfig = {
excludeKeys: [
"fullScreen",
"group-video",
"insertImage"
]
}
this.editorContents = editor.getText();
if (this.editorContents) {
this.editorContent = editor.getHtml();
this.$emit("change", this.editorContent);
} else {
this.$emit("change", "");
}
},
onChange(editor) {
// console.log("onChange", editor.getHtml()); // onChange 时获取编辑器最新内容
this.editorContents = editor.getText();
if (this.editorContents) {
this.editorContent = editor.getHtml();
this.$emit("change", this.editorContent);
} else {
this.$emit("change", "");
}
// this.$emit("change", editor.getHtml());
const toolbar = DomEditor.getToolbar(editor)
console.log("工具栏配置", toolbar.getConfig().toolbarKeys); // 工具栏配置
},
},
});
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style lang="scss">
.notice {
table {
border: none;
border-collapse: collapse;
margin-top: 25px;
}
table td,
table th{
border: 1px solid #ccc;
padding: 3px 5px;
min-width: 50px;
height: 20px;
}
table th {
border-right: 1px solid #ccc;
border-bottom: 2px solid #ccc;
text-align: center;
background-color: #f1f1f1;
}
blockquote{
display: block;
border-left: 8px solid #d0e5f2;
padding: 5px 10px;
margin: 10px 0;
line-height: 1.4;
font-size: 100%;
background-color: #f1f1f1;
}
code{
display: inline-block;
*display: inline;
*zoom: 1;
background-color: #f1f1f1;
border-radius: 3px;
padding: 3px 5px;
margin: 0 3px;
}
pre code {
display: block;
}
ul, ol{
margin: 10px 0 10px 20px;
}
pre {
border: 1px solid #ccc;
background-color: #f8f8f8;
padding: 10px;
margin: 5px 0px;
font-size: 0.8em;
border-radius: 3px;
}
.ql-editor ul li {
list-style-type: disc; // 解决序列li前面的.不展示问题
}
.ql-editor ol li {
list-style-type: decimal; // 解决序列li前面的数字不展示问题
}
}
</style>
3.父组件使用
子组件将文本内容传到父组件,change事件接收内容
以上就可以实现富文本编辑器的使用
注:自己在使用的过程中的遇到的一下麻烦
1.文本内容的回显
可以使用v-html
2.如何移除某些不需要的菜单配置
首先我们可以通过 toolbar.getConfig() 获取工具栏默认配置
import { DomEditor } from '@wangeditor/editor'
const toolbar = DomEditor.getToolbar(editor)
toolbar.getConfig().toolbarKeys
再通过以下代码 将我们不需要的工具移除
this.toolbarConfig = {
excludeKeys: [
"fullScreen",
"group-video",
"insertImage"
]
}
3.富文本回显一些样式丢失 如表格边框 li标签的圆点,我用了notice包裹再外面 防止影响全局样式,所以你们用的时候记得加类!
.notice {
table {
border: none;
border-collapse: collapse;
margin-top: 25px;
}
table td,
table th{
border: 1px solid #ccc;
padding: 3px 5px;
min-width: 50px;
height: 20px;
}
table th {
border-right: 1px solid #ccc;
border-bottom: 2px solid #ccc;
text-align: center;
background-color: #f1f1f1;
}
blockquote{
display: block;
border-left: 8px solid #d0e5f2;
padding: 5px 10px;
margin: 10px 0;
line-height: 1.4;
font-size: 100%;
background-color: #f1f1f1;
}
code{
display: inline-block;
*display: inline;
*zoom: 1;
background-color: #f1f1f1;
border-radius: 3px;
padding: 3px 5px;
margin: 0 3px;
}
pre code {
display: block;
}
ul, ol{
margin: 10px 0 10px 20px;
}
pre {
border: 1px solid #ccc;
background-color: #f8f8f8;
padding: 10px;
margin: 5px 0px;
font-size: 0.8em;
border-radius: 3px;
}
.ql-editor ul li {
list-style-type: disc; // 解决序列li前面的.不展示问题
}
.ql-editor ol li {
list-style-type: decimal; // 解决序列li前面的数字不展示问题
}
}