在components中创建wangEditor组件在页面引入即可
<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" @onChange="onChange" />
</div>
</template>
<script>
import Vue from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { getToken } from '@/utils/auth'
import { delFile } from '@/api/data/room/index.js'
export default Vue.extend({
components: { Editor, Toolbar },
props: {
value: {
type: String,
default: ''
}
},
data() {
return {
oldVideos: [],
newVideos: [],
newImages: [],
oldImages: [],
editor: null,
html: '',
toolbarConfig: {},
editorConfig: {
placeholder: '请输入内容...',
// 所有的菜单配置,都要在 MENU_CONF 属性下
MENU_CONF: {}
},
mode: 'default' // or 'simple'
}
},
watch: {
value(val) {
this.html = val
},
html(val) {
/*使用了v-model的组件会自动监听 input 事件,
* 并把这个input事件所携带的值 传递给v-model所绑定的属性,
* 这样组件内部的值就给到了父组件了
*/
this.$emit('input', val) //传值给父组件, 让父组件监听到这个变化
}
},
methods: {
onCreated(editor) {
this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
},
// 编辑器内容发生变化时
onChange(editor) {
// this.cleanFile()
},
cleanFile() {
// 删除图片
// 获取编辑器中的所有image标签,将所有图片名取出来放到newImages中
this.newImages = this.editor.getElemsByType('image').map(element => {
return element.src
})
this.oldImages.map(item => {
if (!this.newImages.includes(item))
// 调用删除图片的api
delFile(item).then(reponse => {
if (reponse.code == 200) {
this.oldImages = this.oldImages.filter(value => value != item)
console.log(reponse.data)
} else {
console.log(reponse.data)
}
})
})
// 删除视频
this.newVideos = this.editor.getElemsByType('video').map(element => {
return element.src
})
this.oldVideos.map(item => {
if (!this.newVideos.includes(item))
// 调用删除视频的api
delFile(item).then(reponse => {
if (reponse.code == 200) {
this.oldVideos = this.oldVideos.filter(value => value != item)
console.log(reponse.data)
} else {
console.log(reponse.data)
}
})
})
}
},
created() {
this.html = this.value
var that = this
this.editorConfig.MENU_CONF['uploadImage'] = {
server: process.env.VUE_APP_BASE_API + '/file/upload',
fieldName: 'file',
// 单个文件的最大体积限制,默认为 2M
maxFileSize: 5 * 1024 * 1024, // 5M
// 最多可上传几个文件,默认为 100
maxNumberOfFiles: 1,
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedFileTypes: ['image/*'],
// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
meta: {
// token: 'xxx',
// otherKey: 'yyy'
// file:''
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl: false,
// 自定义增加 http header
headers: {
// Accept: 'text/x-json',
// otherKey: 'xxx'
Authorization: 'Bearer ' + getToken()
},
// 跨域是否传递 cookie ,默认为 false
withCredentials: true,
// 超时时间,默认为 10 秒
timeout: 10 * 1000, //10 秒
// 上传前
onBeforeUpload(file) {
var files = Object.values(file)[0]
const isJPG = files.type === 'image/jpeg' || files.type == 'image/png'
const isLt2M = files.size / 1024 / 1024 < 5
if (!isJPG) {
that.$message.error('上传图片只能是 JPG/PNG 格式!')
return false
}
if (!isLt2M) {
that.$message.error('上传图片大小不能超过 5MB!')
return false
}
return file
},
// 自定义插入图片
customInsert(res, insertFn) {
// 因为自定义插入导致onSuccess与onFailed回调函数不起作用,自己手动处理
if (res.code === 200) {
that.$message.success('图片插入成功')
//每次插入图片后把图片名存起来
that.oldImages.push(res.msg)
} else {
that.$message.error(res.msg)
}
insertFn(res.msg)
},
// 上传错误,或者触发 timeout 超时
onError(file, err, res) {
console.log(`${file.name} 上传出错`, err, res.msg)
}
}
// 视频上传
this.editorConfig.MENU_CONF['uploadVideo'] = {
fieldName: 'file',
server: process.env.VUE_APP_BASE_API + '/file/upload',
// 单个文件的最大体积限制,默认为 10M
maxFileSize: 100 * 1024 * 1024, // 100M
// 最多可上传几个文件,默认为 5
maxNumberOfFiles: 1,
// 选择文件时的类型限制,默认为 ['video/*'] 。如不想限制,则设置为 []
allowedFileTypes: ['video/*'],
// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
meta: {
// token: 'xxx',
// otherKey: 'yyy'
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl: false,
// 自定义增加 http header
headers: {
// Accept: 'text/x-json',
// otherKey: 'xxx'
Authorization: 'Bearer ' + getToken()
},
// 跨域是否传递 cookie ,默认为 false
withCredentials: true,
// 超时时间,默认为 30 秒
timeout: 1000 * 1000, // 1000 秒,
// 上传之前触发
onBeforeUpload(file) {
var files = Object.values(file)[0]
const isMp4 = files.type === 'video/mp4'
const is100M = files.size / 1024 / 1024 < 100
if (!isMp4) {
that.$message.error('上传视频只能是 mp4格式!')
return false
}
if (!is100M) {
that.$message.error('上传视频只能小于 100MB!')
return false
}
return file
},
// 自定义插入视频
customInsert(res, insertFn) {
// 因为自定义插入导致onSuccess与onFailed回调函数不起作用,自己手动处理
if (res.code === 200) {
that.$message.success('视频插入成功')
//每次插入视频后把视频名存起来
that.oldVideos.push(res.msg)
} else {
that.$message.error(res.msg)
}
var videoUrl = res.msg
var videoHtml = `<div data-w-e-type="video" data-w-e-is-void>
<video poster="" controls="true" width="640" height="360"><source src="${videoUrl}" type="video/mp4"></video>
</div>`
that.editor.dangerouslyInsertHtml(videoHtml)
},
// 上传错误,或者触发 timeout 超时
onError(file, err, res) {
console.log(`${file.name} 上传出错`, err, res)
Notification.error({
title: '错误',
message: `${file.name} 上传失败,请重新尝试`
})
}
}
},
mounted() {
// 获取描述中的image并赋值到oldImages
setTimeout(() => {
if (this.editor.getElemsByType('image') != 0) {
this.oldImages = this.editor.getElemsByType('image').map(element => {
return element.src
})
}
if (this.editor.getElemsByType('video') != 0) {
this.oldVideos = this.editor.getElemsByType('video').map(element => {
return element.src
})
}
}, 1500)
},
beforeDestroy() {
const editor = this.editor
if (editor == null) return
editor.destroy() // 组件销毁时,及时销毁编辑器
}
})
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
年少轻狂,总以为天下事竭力有为。人事尽时,终感力不能及。