一 介绍
wangEditor5 - 开源 Web 富文本编辑器,开箱即用,配置简单。2022.04.11 正式发布 v5 版本。
官网地址:wangEditor
二 使用
1.安装
支持vue2、vue3、react多框架,这里只介绍vue2使用
npm install @wangeditor/editor --save
npm install @wangeditor/editor-for-vue --save
2.引入模板、script、style文件
模板
<template>
<div style="border: 1px solid #ccc;">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden;"
v-model="html"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="onCreated"
/>
</div>
</template>
script
<script>
import Vue from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
export default Vue.extend({
components: { Editor, Toolbar },
data() {
return {
editor: null,
html: '<p>hello</p>',
toolbarConfig: { },
editorConfig: { placeholder: '请输入内容...' },
mode: 'default', // or 'simple'
}
},
methods: {
onCreated(editor) {
this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
},
},
mounted() {
// 模拟 ajax 请求,异步渲染编辑器
setTimeout(() => {
this.html = '<p>模拟 Ajax 异步设置内容 HTML</p>'
}, 1500)
},
beforeDestroy() {
const editor = this.editor
if (editor == null) return
editor.destroy() // 组件销毁时,及时销毁编辑器
}
})
</script>
style
<style src="@wangeditor/editor/dist/css/style.css"></style>
3.配置工具、菜单栏
查看工具栏配置
console.log(this.editor.getConfig());
const toolbar = DomEditor.getToolbar(this.editor)
const curToolbarConfig = toolbar.getConfig()
console.log( curToolbarConfig.toolbarKeys ) // 排序和分组
工具栏配置
// 工具栏配置(注意结构,否则不起作用)
toolbarConfig: {
excludeKeys :[
'todo',
'codeBlock'
]
},
查看菜单栏配置
console.log(this.editor.getConfig())
菜单栏配置
// 菜单配置(注意结构,否则不起作用)
editorConfig: {
placeholder: "请输入内容...",
MENU_CONF: {
uploadImage: {
// 自定义上传图片 方法
customUpload: this.uploadImg,
// 上传接口设置文件名
fieldName: "file",
meta: {
token: getToken(),
},
},
uploadVideo: {
customUpload: this.uploadVideo,
fieldName: "file",
meta: {
token: getToken(),
},
},
},
},
注:可以通过打印this.editor对象获取对象上的全部方法再找到自己需要使用的。
三 关于绑定问题
1.组件 v-model 绑定数据会默认使用 value 的prop和名为 input 的事件,可以粗浅的理解为 v-model="html"
等效于 v-bind:value="html"
+ v-on:input="(e) => { this.html = e.target.value }"
。
2.封装组件
- 在自定义组件中:
- 我们需要在
props
中定义一个value
来接受父组件传入的值- 然后我们需要使用
$emit('input', newValue)
将新值发送给父组件- 在父组件中:
- 使用
v-model
进行双向绑定
四 代码
editor组件
<template>
<div style="border: 1px solid #ccc">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden"
v-model="html"
:defaultConfig="editorConfig"
:mode="mode"
@onChange="onChange"
@onCreated="onCreated"
/>
</div>
</template>
<script>
import Vue from "vue";
import axios from "axios";
import { getToken } from "@/utils/auth";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
export default Vue.extend({
components: { Editor, Toolbar },
data() {
return {
editor: null,
html: "<p></p>",
currentValue:'',
// 工具栏配置(注意结构,否则不起作用)
toolbarConfig: {
excludeKeys :[
'todo',
'codeBlock'
]
},
// 菜单配置(注意结构,否则不起作用)
editorConfig: {
placeholder: "请输入内容...",
MENU_CONF: {
uploadImage: {
// 自定义上传图片 方法
customUpload: this.uploadImg,
// 上传接口设置文件名
fieldName: "file",
meta: {
token: getToken(),
},
},
uploadVideo: {
customUpload: this.uploadVideo,
fieldName: "file",
meta: {
token: getToken(),
},
},
},
},
mode: "default", // or 'simple'
// 图片、视频上传服务器地址
uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload",
};
},
props: {
/* 编辑器的内容 */
value: {
type: String,
default: "",
},
/* 高度 */
height: {
type: Number,
default: null,
},
/* 最小高度 */
minHeight: {
type: Number,
default: null,
},
/* 只读 */
readOnly: {
type: Boolean,
default: false,
},
// 上传文件大小限制(MB)
fileSize: {
type: Number,
default: 5,
},
/* 类型(base64格式、url格式) */
type: {
type: String,
default: "url",
},
},
watch: {
// 监听父组件中editor值的变化
value: {
handler(val) {
this.html=val
this.currentValue=val
},
immediate: true,
},
},
mounted() {
this.initEditor();
},
methods: {
onCreated(editor) {
// 一定要用 Object.seal() ,否则会报错
this.editor = Object.seal(editor);
},
onChange(editor){
// this.$emit("change", this.html);
// this.value=this.html
this.$emit('input', this.html)
},
//自定义上传视频
uploadVideo(file, insertFn) {
let imgData = new FormData();
imgData.append("file", file);
axios({
url: this.uploadFileUrl,
data: imgData,
method: "post",
headers: {
Authorization: "Bearer " + getToken(),
},
}).then((response) => {
if (response.data.code === 200) {
// 插入后端返回的url,将图片显示在页面上
insertFn(response.data.url);
this.$message({
type: "success",
message: "上传成功",
});
} else {
}
});
},
//自定义上传图片
uploadImg(file, insertFn) {
let imgData = new FormData();
imgData.append("file", file);
axios({
url: this.uploadFileUrl,
data: imgData,
method: "post",
headers: {
Authorization: "Bearer " + getToken(),
},
}).then((response) => {
if (response.data.code === 200) {
// 插入后端返回的url
insertFn(response.data.url);
this.$message({
type: "success",
message: "上传成功",
});
} else {
}
});
},
},
mounted() {
// 模拟 ajax 请求,异步渲染编辑器
setTimeout(() => {
if(this.currentValue){
this.html=this.currentValue
}
// 查看菜单配置项
// console.log(this.editor.getConfig());
// const toolbar = DomEditor.getToolbar(this.editor)
// const curToolbarConfig = toolbar.getConfig()
// console.log( curToolbarConfig.toolbarKeys ) // 当前菜单排序和分组
}, 1500);
},
beforeDestroy() {
const editor = this.editor;
if (editor == null) return;
editor.destroy(); // 组件销毁时,及时销毁编辑器
},
});
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
父组件
<template>
<div id="app">
<wang-editor :option="option" v-model="html"></wang-editor>
</div>
</template>
<script>
import WangEditor from './components/wang-editor.vue'
export default {
name: 'App',
components: {
WangEditor
},
data() {
return {
option: {
height: 500
},
html: '<p></p>'
}
},
}
</script>
五 补充:
富文本框默认字体大小修改:
<style>
.w-e-text-container{
font-size: 19px!important;
}
</style>
可利用开发者工具找到富文本框文字展示的类名,另写样式覆盖默认sytle文件中默认样式即可。