wangEditor是前端一个比较流行的简洁易用,功能强大的前端富文本编辑器,支持 JS Vue React,提供了很多丰富的功能,下面手把手教你实现wangWditor富文本插件在vue项目中配置,保存、图片上传等功能。无脑ctrl+c即可
基本功能入如下:
template
<div class="editor-wrap">
<p class="title">发布文章</p>
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden; border-bottom: 1px solid #ccc"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
/>
</div>
script
<script setup lang="ts">
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { ref, onBeforeUnmount, onMounted, shallowRef, watchEffect, onUnmounted } from 'vue'
// import '@wangeditor/editor/dist/css/style.css' // 试了几次无效,直接把样式复制到本地后引入
import '@/styles/editorStyle.css'
import { getToken } from '@/utils/cookie'
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef()
// 定义组件的本地状态
const mode = ref('simple') // 或 'default, simple'
// 内容 HTML
const valueHtml = ref('<p>hello</p>')
// 模拟 ajax 异步获取内容
onMounted(() => {
setTimeout(() => {
valueHtml.value = '<p>模拟 Ajax 异步设置内容</p>'
}, 1500)
})
// 菜单栏配置项,下面卧虎列出所有菜单配置,直观展示所有菜单,使用editorRef.value.getAllMenuKeys()也可以获取全部菜单的key
const toolbarConfig = {}
toolbarConfig.toolbarKeys = [
"bold",
"underline",
"italic",
"through",
// "code",
// "sub",
// "sup",
"clearStyle",
"color",
"bgColor",
"fontSize",
"fontFamily",
"indent",
"delIndent",
"justifyLeft",
"justifyRight",
"justifyCenter",
"justifyJustify",
"lineHeight",
// "insertImage",
// "deleteImage",
// "editImage",
// "viewImageLink",
// "imageWidth30",
// "imageWidth50",
// "imageWidth100",
// "divider",
// "emotion",
// "insertLink",
// "editLink",
// "unLink",
// "viewLink",
"codeBlock",
"blockquote",
"headerSelect",
"header1",
"header2",
"header3",
"header4",
"header5",
"todo",
"redo",
"undo",
// "fullScreen",
// "enter",
// "bulletedList",
// "numberedList",
// "insertTable",
// "deleteTable",
// "insertTableRow",
// "deleteTableRow",
// "insertTableCol",
// "deleteTableCol",
// "tableHeader",
// "tableFullWidth",
// "insertVideo",
// "uploadVideo",
// "editVideoSize",
"uploadImage",
// "codeSelectLang"
]
//编辑器配置
const editorConfig = {
placeholder: '请输入内容...',
MENU_CONF: {
// 图片上传
uploadImage: {
server: '/dev-api/upload-image', //上传的api地址
// fieldName: 'img', //这个是form-data流上传的文件名,自己根据需求修改
fieldName: 'file',
// 单个文件的最大体积限制,默认为 2M
maximgSize: 10 * 1024 * 1024, // 10M
// 最多可上传几个文件,默认为 100
maxNumberOfimgs: 10,
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedimgTypes: ['image/*'],
// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
meta: {
// token: 'xxx',
// otherKey: 'yyy'
// img:''
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl: false,
// 自定义增加 http header
headers: {
// 这里可以新增一些header自定义参数
authorization: getToken(),
// Accept: 'text/x-json',
// otherKey: 'xxx'
},
// 跨域是否传递 cookie ,默认为 false
withCredentials: true,
// 超时时间,默认为 10 秒
timeout: 10 * 1000, //10 秒
// 上传前
onBeforeUpload(imgs) {
ElMessage({
message: '图片正在上传中,请耐心等待',
grouping: true,
duration: 0,
customClass: 'uploadTip',
iconClass: 'el-icon-loading',
showClose: true
});
return imgs;
},
// 自定义插入图片
customInsert(res, insertFn) {
// 因为自定义插入导致onSuccess与onFailed回调函数不起作用,自己手动处理
// 先关闭等待的ElMessage
ElMessage.closeAll();
if (res.code === 200) {
ElMessage.success({
message: "图片上传成功",
grouping: true,
});
// 获取到服务端响应的图片链接插入编辑器
insertFn(res.data.url);
} else {
ElMessage.error({
message: "图片上传失败,请重新尝试",
grouping: true,
});
}
},
// 单个文件上传成功之后
onSuccess(img, res) {
// console.log(`${img.name} 上传成功`, res);
console.log('img', img)
console.log('res', res)
},
// 单个文件上传失败
onFailed(img, res) {
console.log(`${img.name} 上传失败`, res);
},
// 上传进度的回调函数
onProgress(progress) {
console.log('progress', progress);
// progress 是 0-100 的数字
},
// 上传错误,或者触发 timeout 超时
onError(img, err, res) {
console.log(`${img.name} 上传出错`, err, res);
}
}
},
}
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor == null) return
editor.destroy()
})
// 定义一个 handleCreated 函数,用于记录 editor 实例
const handleCreated = (editor) => {
editorRef.value = editor // 记录 editor 实例,重要!
}
</script>
这样一个非常简单又强大的富文本编辑器就实现了,效果如下:
视频等其他文件上传同理。
富文本内容保存直接使用valueHtml或者editorRef.value.getHtml()即可。