1.项目安装wangEditor
npm install wangeditor/editor
npm install wangeditor/editor-for-vue
2.vue页面引用wangEditor组件
<template lang="html">
<div style="border: 1px solid #ccc;" class="editor">
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig" :mode="mode" />
<Editor style="height: 400px; overflow-y: hidden;" v-model="html" @input="handleInput"
:defaultConfig="editorConfig" :mode="mode" @onCreated="onCreated" @onChange="onChange"
@onMaxLength="onMaxLength" />
</div>
</template>
<script>
import Vue from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { DomEditor } from '@wangeditor/editor'
import { uploadF, downloadF } from '@/api/file/file'
import '@wangeditor/editor/dist/css/style.css'
// import { uploadFile } from '@/api/informationRelease/newsList'
// const toolbarConfig = { // JS 语法
// /* 工具栏配置 */
// }
export default Vue.extend({
components: { Editor, Toolbar },
model: {
prop: "value", // v-model 接收的值=props的message属性接收的值
event: "change" // v-model 发生变化时触发的方法
},
props: {
value: {
// 富文本数据
type: String,
default: ""
},
id: {
type: String,
default: ''
},
maxLength: {
type: Number,
default: 10000
}
},
watch: {
value: function (value) {
// 如果值不相等再进行赋值,避免多次赋值造成闪烁
if (value !== this.html) {
this.html = this.value;
}
}
// value为编辑框输入的内容,这里我监听了一下值,当父组件调用得时候,如果给value赋值了,子组件将会显示父组件赋给的值
},
data() {
return {
editor: null,
html: '',
textLength: 0,
// 编辑器模式
mode: "default", // or 'simple'
toolbarConfig: {
// 排除工具栏配置
excludeKeys: [
// 全屏,网络视频,本地视频,表情,代码,待办,代码块,插入图片
'fullScreen', 'uploadVideo', 'group-video', 'emotion', 'code', 'todo', 'codeBlock', 'insertImage'
]
},
italicButton: null,
editorConfig: {
placeholder: '请输入内容...',
maxLength: this.maxLength, // 限制富文本输入文本字数
MENU_CONF: {
uploadImage: {
// 最多可上传几个文件,默认为 100
// maxNumberOfFiles: 10,
// 单个文件的最大体积限制,默认为 2M
maxFileSize: 1 * 1024 * 1024, // 1M
// 小于该值就插入 base64 格式(而不上传),默认为 0
base64LimitSize: 5 * 1024, // 5kb
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制
allowedFileTypes: ["image/*"],
// 图片上传
async customUpload(file, insertFn) {
const formData = new FormData()
formData.append('multipartFile', file)
const res = await uploadF(formData)
if (res.data) {
insertFn(`图片地址`, 'image')
} else {
this.$message.error('图片上传失败,请重新上传!');
}
}
},
fontFamily: {
fontFamilyList: [
{ name: '仿宋', value: 'fangsong' },
{ name: '黑体', value: 'Arial' },
{ name: '仿手写', value: 'cursive' },
'serif',
'sans-serif',
]
}
}
},
// Toolbar对象
curToolbarConfig: null
}
},
methods: {
onCreated(editor) {
this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
this.$nextTick(() => {
const toolbar = DomEditor.getToolbar(this.editor);
this.curToolbarConfig = toolbar.getConfig();
});
},
handleInput(value) {
this.$emit("change", value); // 将内容同步到父组件中
},
onChange(editor) { // 监听富文本输入
const text = editor.getText().replace(/\n|\r/mg, '')
this.textLength = text.length
},
onMaxLength(editor) { // 当输入值达到限制值时触发事件
this.$message.warning('输入文本数已到达最大值!')
},
},
mounted() {},
beforeDestroy() {
const editor = this.editor
if (editor == null) return
editor.destroy() // 组件销毁时,及时销毁编辑器
},
})
</script>
.editor {
a { //
color: #09A057;
border-bottom: 1px solid #09A057;
}
.italic {
font-style: italic; // 若富文本的斜体样式不生效时,加上此样式
}
.w-e-bar-item {
}
若回显富文本时样式出现问题将样式引入即可,必须将style标签的scoped字段删掉样式才能生效 (editor-content-view是自己定义的类名)
.editor-content-view {
border-radius: 5px;
padding: 0 10px;
overflow-x: auto;
a{
color: #09A057;
border-bottom: 1px solid #09A057;
}
}
.editor-content-view p,
.editor-content-view li {
white-space: pre-wrap; /* 保留空格 */
}
.editor-content-view blockquote {
border-left: 8px solid #d0e5f2;
padding: 10px 10px;
margin: 10px 0;
background-color: #f1f1f1;
}
.editor-content-view code {
font-family: monospace;
background-color: #eee;
padding: 3px;
border-radius: 3px;
}
.editor-content-view pre>code {
display: block;
padding: 10px;
}
.editor-content-view table {
border-collapse: collapse;
}
.editor-content-view td,
.editor-content-view th {
border: 1px solid #ccc;
min-width: 50px;
height: 20px;
}
.editor-content-view th {
background-color: #f1f1f1;
}
.editor-content-view ul,
.editor-content-view ol {
padding-left: 20px;
}
.editor-content-view ul >li {
list-style: disc;
}
.editor-content-view ol >li {
list-style: auto;
}
.editor-content-view input[type="checkbox"] {
margin-right: 5px;
}
.editor-content-view em{
font-style: italic;
}