1、参考官方的wangeditor5-for–vue3的开发手册
官方文档地址:https://clinfc.github.io/wangeditor5-for–vue3/guide/
官方文档的使用手册对于新手来说比较的难看懂,写的也不够详细,源码的封装比较深。写博客的目的是为了详细讲解一个适合项目使用的wangeditor的基本全过程,适合直接复制使用和修改(原官方文档使用原生js编写)
2、下载编辑器的依赖
npm install @wangeditor/editor --save
npm install @wangeditor/editor-for-vue@next --save
# 下面是vue3单独的组件,上面两个是旧的
npm install @wangeditor/editor wangeditor5-for-vue3
21.、新旧组件对比
旧组件
<template>
<div style="border: 1px solid #ccc">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden;"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
/>
</div>
</template>
新组件
<template>
<we-editor
toolbar-class="toolbar"
editable-class="editable"
toolbar-style="border: 1px solid #d9d9d9"
editable-style="border: 1px solid #d9d9d9"
:toolbar-option="toolbar"
:editable-option="editable"
:toolbar-reloadbefore="onToolbarReloadBefore"
:editable-reloadbefore="onEditableReloadBefore"
v-model="formData.jarr"
v-model:json="formData.jstr"
v-model:html="formData.html"
/>
</template>
3、入门使用<we-editor>组件
3.1、使用上面的新组件
3.2、编写js代码
<script>
// 引入 wangeditor5 样式
import '@wangeditor/editor/dist/css/style.css'
import { WeEditor, useWangEditor } from 'wangeditor5-for-vue3'
import { defineComponent, shallowReactive } from 'vue'
export default defineComponent( {
name: "wangeditor",
components: { WeEditor },
setup() {
// 编辑器配置
const editableOption = {}
// 菜单栏配置
const toolbarOption = {}
// 防抖时长。当会触发重载的配置项发生变化 365ms 后,编辑器会重载
const reloadDelary = 365
// 对于上面的三个对象,经过 useWangEditor 处理后,返回的 editable 和 toolbar 分别对应编辑器和菜单栏的配置项
const { editable, toolbar } = useWangEditor(
editableOption,
toolbarOption,
reloadDelary
)
// 开启只读模式【不可编辑】
editable.config.readOnly = false
// 不要使用 reactive/ref,应该使用 shallowReactive/shallowRef 来接收 json array 数据
const formData = shallowReactive({ jarr: [], jstr: '', html: '' })
// 在可编辑的重新加载之前
function onEditableReloadBefore(inst) {
console.log(inst)
console.log('editable 即将重载: ' + new Date().toLocaleString())
}
// 在工具栏上重新加载之前
function onToolbarReloadBefore(inst) {
console.log(inst)
console.log('toolbar 即将重载: ' + new Date().toLocaleString())
}
return { editable, toolbar, formData, onEditableReloadBefore, onToolbarReloadBefore }
},
})
</script>
useWangEditor的官方说明
经过 useWangEditor
处理后,返回的 editable
和 toolbar
分别对应编辑器和菜单栏的配置项,不过此时的配置项对象具备了响应式特性,我们可以直接修改 editable
/toolbar
对应属性来更新或重载编辑器。
如果传入的 editableOption
和 toolbarOption
是响应式数据,内部将自动解除与之前的关联,也就意味着经过 useWangEditor
处理后得到的 editable
和 toolbar
配置对象,即使内容发生变化也不会触发之前的依赖更新!!!
大白话:可以在useWangEditor之后的对象中编写,也可以直接在editableOption对象中编写好再进过useWangEditor处理,不建议各自写一点,因为会覆盖,要么在前面写要么在后面写
3.3、编写样式
原来组件上面通过
toolbar-style="border: 1px solid #d9d9d9"editable-style="border: 1px solid #d9d9d9"
来指定了工具栏和编辑器的样式边框,通过查看DOM元素赋值如下
<style>
/*工具栏样式*/
.toolbar{
border: 1px solid #d9d9d9;margin-bottom: 10px;
}
/*工具栏剧中显示*/
.w-e-toolbar {
justify-content: center !important;
}
/*编辑器样式*/
.editable{
border: 1px solid #d9d9d9;
min-height: 800px;
width: 850px;
margin: 30px auto 150px auto;
background-color: #fff;
box-shadow: 0 2px 10px rgb(0 0 0 / 12%);
border: 1px solid #e8e8e8;
}
</style>
4、工具栏的修改(toolbarOption)
4.1、获取工具栏默认配置
toolbar.getConfig()
4.2、查看当前工具栏的默认配置
toolbar.getConfig().toolbarKeys
4.3、查询编辑器注册的所有菜单 key (可能有的不在工具栏上)
editor.getAllMenuKeys()
4.4、操作过程
4.5、工具栏模式对比及修改
// 菜单栏配置
const toolbarOption = {
mode: 'simple' // 指定简介模式
}
方式二、通过useWangEditor
转换后的toolbar
进行重新
// 对于上面的三个对象,经过 useWangEditor 处理后,返回的 editable 和 toolbar 分别对应编辑器和菜单栏的配置项
const { editable, toolbar } = useWangEditor(
editableOption,
toolbarOption,
reloadDelary
)
toolbar.mode = 'default'
4.6、重新配置工具栏,显示哪些菜单,以及菜单的排序、分组
[
"headerSelect",
"blockquote",
"codeBlock",
"|",
"bold",
"underline",
"italic",
{
key: "group-more-style",
title: "更多",
iconSvg: "<svg viewBox="0 0 1024 1024">" +
"<path d="M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path>" +
"<path d="M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path>" +
"<path d="M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path>" +
"</svg>",
menuKeys: ["through", "code", "sup", "sub", "clearStyle"]
},
"color",
"bgColor",
"|",
"fontSize",
"fontFamily",
"lineHeight",
"|",
"bulletedList",
"numberedList",
"todo",
{
key: "group-justify",
iconSvg: "<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>",
title: "对齐",
menuKeys: ["justifyLeft", "justifyRight", "justifyCenter", "justifyJustify"]
},
{
key: "group-indent",
title: "缩进",
iconSvg: "<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z"></path></svg>",
menuKeys: ["indent", "delIndent"]
},
"|",
"emotion",
"insertLink",
{
key: "group-image",
title: "图片",
iconSvg: "<svg viewBox="0 0 1024 1024"><path d="M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z"></path></svg>",
menuKeys: ["insertImage", "uploadImage"]
},
{
key: "group-video",
title: "视频",
iconSvg: "<svg viewBox="0 0 1024 1024"><path d="M981.184 160.096C837.568 139.456 678.848 128 512 128S186.432 139.456 42.816 160.096C15.296 267.808 0 386.848 0 512s15.264 244.16 42.816 351.904C186.464 884.544 345.152 896 512 896s325.568-11.456 469.184-32.096C1008.704 756.192 1024 637.152 1024 512s-15.264-244.16-42.816-351.904zM384 704V320l320 192-320 192z"></path></svg>",
menuKeys: ["insertVideo", "uploadVideo"]
},
"insertTable",
"divider",
"|",
"undo",
"redo",
"|",
"fullScreen"
]
注意:如果想在
useWangEditor
处理后的toolbar
对象修改,必须要在toolbarOption
对象里面先创建空的一个config
配置空对象后面才能修改到(来源一个网友的说法)
// 菜单栏配置
const toolbarOption = {
mode: 'simple', // 指定简介模式
config:{
toolbarKeys:[
"fontSize",'header1', 'header2', 'header3','header4','|',
'blockquote',"code","codeBlock",'|',
'bold', 'underline', 'italic', 'through', 'color', 'bgColor', 'clearStyle', '|',
'bulletedList', 'numberedList', 'todo', 'justifyLeft','justifyCenter', 'justifyRight', '|',
'insertLink',
{
key: 'group-image',
title: '图片',
iconSvg: "<svg viewBox="0 0 1024 1024"><path d="M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z"></path></svg>",
menuKeys: ['insertImage', 'uploadImage']
},
"insertTable",
"|",
"undo","redo"
]
}
}
5、菜单配置(editableOption)
根据官网描述:wangEditor 从 V5 版本开始,工具栏配置和菜单配置(如配置颜色、字体、链接校验、上传图片等)分离了
5.1、查看编辑器配置
可通过
editor.getConfig()
查看编辑器默认配置
在4的步骤中使用
editor.getAllMenuKeys()
以及获取到了所有的菜单key,就可以进行下一步的菜单配置了
5.2、配置默认字号
如何查看keys和配置项?通过上图就可以看出对应的key,找到
fontSize
,点击进去就有fontSizeList
数组了,根据里面的写法进行编写即可
// 编辑器配置
const editableOption = {
config:{
MENU_CONF:{
fontSize:{
fontSizeList: [
// 元素支持两种形式
// 1. 字符串;
// 2. { name: 'xxx', value: 'xxx' }
'16px',
'20px',
{ name: '26px', value: '26px' },
'40px',
]
}
}
}
}
效果如下
5.3、图片上传配置
我这里引入了
ElementUI
的插件所以可以使用this.$message.success(
${file.name} 上传成功, res)
作为提示后台的上传地址
server
需要自己编写能实现上传文件再进行测试// 成功返回 { "errno": 0, // 注意:值是数字,不能是字符串 "data": { "url": "xxx", // 图片 src ,必须 "alt": "yyy", // 图片描述文字,非必须 "href": "zzz" // 图片的链接,非必须 } } // 失败返回 { "errno": 1, // 只要不等于 0 就行 "message": "失败信息" }
// 编辑器配置
const editableOption = {
config:{
placeholder:"请在这里输入内容...",
MENU_CONF:{
// 配置默认字号
// 配置上传图片
uploadImage:{
// 请求路径
server: "api/sysUser/uploadImg",
// 后端接收的文件名称
fieldName: "file",
maxFileSize: 1 * 1024 * 1024, // 1M
// 上传的图片类型
allowedFileTypes: ["image/*"],
// 小于该值就插入 base64 格式(而不上传),默认为 0
base64LimitSize: 10 * 1024, // 10MB
// 自定义插入返回格式【后端返回的格式】
customInsert(res, insertFn) {
if(res.code != 200 && res.success == false){
ElMessage.error("上传文件失败,"+res.message)
return
}
insertFn(res.data.url, res.data.alt, res.data.href)
},
// 携带的数据
meta: {
token: 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2NjM0MjQ5MzEsInN1YiI6ImFkbWluIiwiaWF0IjoxNjYzNDIzMTMxOTAyfQ.McM6MZ6N9dQnAKym-9_TqAv6gjRWqf72Q4MTnMlS9AeIM-DhCjaJJrUMYbB8hs5r-HXYSXbs5O5pk9f_KUbGQg'
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl: true,
// 单个文件上传成功之后
onSuccess(file, res) {
if(res.code == 200 && res.success){
ElMessage.success(`${file.name} 上传成功`)
return
}else {
ElMessage.warning(`${file.name} 上传出了点异常`)
return
}
// console.log(`${file.name} 上传成功`, res)
//ElMessage.success(`${file.name} 上传成功`, res)
},
// 单个文件上传失败
onFailed(file, res) {
console.log(res)
ElMessage.error(`${file.name} 上传失败`)
},
// 上传错误,或者触发 timeout 超时
onError(file, err, res) {
console.log(err, res)
ElMessage.error(`${file.name} 上传出错`)
},
}
}
}
}
5.4、视频上传
6、上传附件插件使用
官方插件地址:https://github.com/wangeditor-team/wangEditor-plugin–upload–attachment
6.1、下载依赖
-
npm install --global yarn # 检查是否成功 yarn --version
-
yarn add @wangeditor/plugin-upload-attachment
跟着上面步骤走的就通过下面的方式获取到(原先已近下载了其他依赖)
npm i @wangeditor/plugin-upload-attachment -s
-
查看
6.2、【注意】该文档要求 @wangeditor/editor
版本 >=5.1.16
6.3、注册到编辑器
import { Boot } from '@wangeditor/editor'
import attachmentModule from '@wangeditor/plugin-upload-attachment'
import { WeEditor, useWangEditor } from 'wangeditor5-for-vue3'
// 注册。要在创建编辑器之前注册,且只能注册一次,不可重复注册。
Boot.registerModule(attachmentModule)
6.4、编辑器配置上传附件菜单
注意:如果在useWangEditor
处理后的editable
使用也需要在editableOptionconfig.MENU_CONF.uploadAttachment
的空对象
// 编辑器配置
const editableOption = {
config:{
hoverbarKeys: {
attachment: {
menuKeys: ['downloadAttachment'], // “下载附件”菜单
},
},
MENU_CONF: {
// 上传附件
uploadAttachment:{
server: 'http://localhost:8081/api/sysUser/blogFileUpload',
fieldName: 'file',
maxFileSize: 100 * 1024 * 1024, // 100M
// 携带的数据
meta: {
token: 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2NjM0MTQ1MjAsInN1YiI6ImFkbWluIiwiaWF0IjoxNjYzNDEyNzIwMDE5fQ.nFAEtMqduzValgDAsMUXeM0OSIlYK4hi8cjTSAL52jMgFwfuOUVNEbdT91abs1rdNXKjEtrymbn_2aO1Q2h26Q'
},
// 在上传之前
onBeforeUpload(file) {
console.log('onBeforeUpload', file)
return file // 上传 file 文件
// return false // 会阻止上传
},
// 关于进展
onProgress(progress) {
console.log('onProgress', progress)
},
// 成功回调
onSuccess(file, res) {
if(res.errno === 0){
ElMessage.success(`${file}附件上传成功`)
}
},
// 失败回调
onFailed(file, res) {
if(res.errno === 1){
ElMessage.success(`${file}附件上传失败,`+res.message)
}
},
// 错误
onError(file, err, res) {
console.error('onError', file, err, res)
},
// // 上传成功后,用户自定义插入文件
// customInsert(res: any, file: File, insertFn: Function) {
// console.log('customInsert', res)
// const { url } = res.data || {}
// if (!url) throw new Error(`url is empty`)
// // 插入附件到编辑器
// insertFn(`customInsert-${file.name}`, url)
// },
// // 用户自定义上传
// customUpload(file: File, insertFn: Function) {
// console.log('customUpload', file)
// return new Promise(resolve => {
// // 插入一个文件,模拟异步
// setTimeout(() => {
// const src = `https://www.w3school.com.cn/i/movie.ogg`
// insertFn(`customUpload-${file.name}`, src)
// resolve('ok')
// }, 500)
// })
// },
// // 自定义选择
// customBrowseAndUpload(insertFn: Function) {
// alert('自定义选择文件,如弹出图床')
// // 自己上传文件
// // 上传之后用 insertFn(fileName, link) 插入到编辑器
// },
// 插入到编辑器后的回调
onInsertedAttachment(elem) {
console.log(elem)
}
},
}
}
}
6.5、工具栏插件附件按钮
方式一
const toolbarOption = {
config:{
// 插入哪些菜单
insertKeys: {
index: 0, // 自定义插入的位置
keys: ['uploadAttachment'], // “上传附件”菜单
},
}
}
方式二
const toolbarOption = {
config:{
// 插入哪些菜单
toolbarKeys:[
"fontSize",'header1', 'header2', 'header3','header4','|',
'blockquote',"code","codeBlock",'uploadAttachment','|',
....
]
}
}
6.6、后端数据响应格式
成功
{
"errno": 0,
"data": {
"url": "附件的下载链接"
}
}
失败
{
"errno": 1,
"message": "错误信息"
}
<a data-w-e-type="attachment" data-w-e-is-void data-w-e-is-inline href="https://xxx.com/aaa/bbb/xxx.zip" download="xxx.zip">xxx.zip</a>
6.7、上传附件测试
hoverbarKeys: {
attachment: {
menuKeys: ['downloadAttachment'], // “下载附件”菜单
},
},
7、模型双向绑定
WeEditable
/WeEditor
/WeEditorPlus
组件同时支持 v-model
、v-model:json
和 v-model:html
三种形式的双向绑定,分别对应 json array
、json string
和 html string
三种格式的数据。
注意事项:
- 注意
WeEditableOption.extendCache
可能存在的影响!!! - 当我们进行
v-model
绑定时,推荐使用shallowReactive
/shallowRef
来缓存json array
数据。如果你执意使用reactive
/ref
进行数据缓存,那么在出现未知错误时你可能找不到问题所在。 - 在提交表单前,或手动触发表单验证前,请使用
syncContent
来强制同步v-model
数据,避免数据不一致。 - 双向绑定多个同时使用时,存在
v-model
>v-model:json
>v-model:html
的优先级关系。即:如果你使用优先级低的来设置数据的话,设置将被拦截(设置无效)。
最优搭配为
v-html:json
或v-model:json
+v-model:html
。v-model:json
相对v-model
而言,能减少大量内存消耗和计算消耗。
7.1、获取数据
在
useWangEditor
处理后的时候一个syncContent
,才能使获取到的数据同步,返回submit
方法,给按钮绑定点击事件调用即可
setup() {
....
// 对于上面的三个对象,经过 useWangEditor 处理后,返回的 editable 和 toolbar 分别对应编辑器和菜单栏的配置项
const { editable, toolbar ,syncContent } = useWangEditor(
editableOption,
toolbarOption,
reloadDelary,
{
delay: 3000, // 无操作 3s 后才会同步表单数据
config: {
placeholder: '表单提交前使用 syncContent API 强制同步数据,确保数据不被丢失',
},
}
)
// 获取数据
const formData = shallowReactive({ html: '' })
....
// 表单提交
function submit() {
// 强制同步 v-model 数据
syncContent()
// 表单验证
if(formData.html!=''){
// TODO 进行业务处理
ElMessage.success(formData.html)
}else {
ElMessage.error("请在编辑器内编写内容...")
}
}
return { editable, toolbar, formData, submit,onEditableReloadBefore, onToolbarReloadBefore }
}
原文地址:https://blog.csdn.net/baidu_39378193/article/details/126916335
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_44852.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!