安装
javascript
npm install @wangeditor/editor --save
npm install @wangeditor/editor-for-vue --save
npm install @wangeditor/plugin-upload-attachment//附件使用
vue
图片上传、视频上传、附件上传
javascript
<template lang="html">
<div style="border: 1px solid #ccc;width:840px" class="editors">
<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 "@wangeditor/editor/dist/css/style.css";
import { getToken } from "@/utils/auth";
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: 10000000,
},
},
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",
],
insertKeys: {
index: 22, // 自定义插件在工具栏显示的位置
keys: ["uploadAttachment"], // 查看名称
},
hoverbarKeys: {
attachment: {
menuKeys: ["downloadAttachment"], // "下载附件"菜单
},
},
},
italicButton: null,
editorConfig: {
placeholder: "请输入内容...",
maxLength: this.maxLength, // 限制富文本输入文本字数
MENU_CONF: {
uploadImage: {
server: process.env.VUE_APP_BASE_API + "/file",
timeout: 100000,
maxFileSize: 10000 * 1024 * 1024,
base64LimitSize: 50000 * 1024,
},
uploadVideo: {
fieldName: "file",
server: process.env.VUE_APP_BASE_API + "/file",
timeout: 1000000,
maxFileSize: 10000 * 1024 * 1024, // 1M
base64LimitSize: 50000 * 1024,
headers: {
Authorization: getToken(),
},
async customInsert(insertFn, result) {
if (insertFn.code === 0) {
result(insertFn.data[0]);
} else {
this.$message.error("视频上传失败,请重新上传!");
}
},
},
uploadAttachment: {
fieldName: "file",
server: process.env.VUE_APP_BASE_API + "/file",
timeout: 1000000,
headers: {
Authorization: getToken(),
},
async customInsert(res, file,insertFn) {
insertFn(
file.name,
res.data[0]
);
},
},
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("input", value); // 将内容同步到父组件中
},
onChange(editor) {
// 监听富文本输入
const text = editor.getText().replace(/\n|\r/gm, "");
this.textLength = text.length;
},
onMaxLength(editor) {
// 当输入值达到限制值时触发事件
this.$message.warning("输入文本数已到达最大值!");
},
},
mounted() {},
beforeDestroy() {
const editor = this.editor;
if (editor == null) return;
editor.destroy(); // 组件销毁时,及时销毁编辑器
},
});
</script>
<style lang="scss" scoped>
::v-deep .w-e-textarea-video-container {
background-image: none;
}
</style>
main.js
javascript
import {Boot} from '@wangeditor/editor'
import attachmentModule from '@wangeditor/plugin-upload-attachment'
Boot.registerModule(attachmentModule)