0


wangeditor5在vue3中的全使用过程(图片上传、附件上传、工具栏配置、编辑器配置)

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4L9P2FUX-1663476493749)(image/1、wangeditor依赖.png)]

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>

新组件

WeEditor

组件将

WeToolbar

WeEditable

组件封装在了一个组件中,使用更方便。

<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、入门使用组件

创建一个新的vue页面来编写当前demo

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 defaultdefineComponent({
    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 即将重载: ' +newDate().toLocaleString())}// 在工具栏上重新加载之前
        function onToolbarReloadBefore(inst){
            console.log(inst)
            console.log('toolbar 即将重载: ' +newDate().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:02px 10px rgb(000/12%);
    border:1px solid #e8e8e8;}</style>

初始化效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b3znbMhl-1663476493750)(image/2、编辑器效果.png)]

4、工具栏的修改(toolbarOption)

关于工具栏的排序以及菜单的配置的获取,根据官网的语句通过vue方法获取我暂时没弄懂,所以通过原生的方式获取

4.1、获取工具栏默认配置

进入官方提供的Demo示例,按F12输入如下命令查看工具栏的默认配置

toolbar.getConfig()

4.2、查看当前工具栏的默认配置

toolbar.getConfig().toolbarKeys

4.3、查询编辑器注册的所有菜单 key (可能有的不在工具栏上)

editor.getAllMenuKeys()

4.4、操作过程

官方demo地址:https://www.wangeditor.com/demo/index.html

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sQDyZiVO-1663476493751)(image/3、浏览器查看配置.png)]

4.5、工具栏模式对比及修改

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2bAWSN5C-1663476493751)(image/4、工具栏模式对比.png)]

方式一,直接在菜单栏配置对象里面写

// 菜单栏配置const toolbarOption ={mode:'simple'// 指定简介模式}

方式二、通过

useWangEditor

转换后的

toolbar

进行重新

注意:后面的配置会覆盖前面的配置,所以当前设置的模式为

default

被后面所覆盖了

默认配置建议在

toolbarOption

写好在通过

useWangEditor

转换

// 对于上面的三个对象,经过 useWangEditor 处理后,返回的 editable 和 toolbar 分别对应编辑器和菜单栏的配置项const{ editable, toolbar }=useWangEditor(
    editableOption,
    toolbarOption,
    reloadDelary
)

toolbar.mode ='default'

4.6、重新配置工具栏,显示哪些菜单,以及菜单的排序、分组

根据上面的4.2步骤获取到了当前默认的工具栏配置如下,与工具栏一一对应

["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"]}}

简洁效果如下

后面再加入个

附件上传的插件菜单

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EB3KioWj-1663476493752)(image/5、简洁排序.png)]

5、菜单配置(editableOption)

根据官网描述:wangEditor 从 V5 版本开始,工具栏配置和菜单配置(如配置颜色、字体、链接校验、上传图片等)分离了

菜单配置是什么?就是上图中的选择默认字体大小类的内容,也就是工具栏的菜单功能实现

5.1、查看编辑器配置

可通过

editor.getConfig()

查看编辑器默认配置

根据下图观察,editor后面使用的是getConfig是一个配置,所以下面的配置页要写在config对象里面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2BL4YauT-1663476493752)(image/6、查看编辑器配置.png)]

在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',]}}}}

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UvzFqXw0-1663476493753)(image/7、修改默认子号.png)]

5.3、图片上传配置

根据查询的ket查看如何配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tp0SN8B9-1663476493753)(image/8、查看上传图片配置.png)]

实现

我这里引入了

ElementUI

的插件所以可以使用

this.$message.success(

${file.name} 上传成功

, res)

作为提示

后台的上传地址

server

需要自己编写能实现上传文件再进行测试

官方上传文件的返回类型

// 成功返回{"errno":0,// 注意:值是数字,不能是字符串"data":{"url":"xxx",// 图片 src ,必须"alt":"yyy",// 图片描述文字,非必须"href":"zzz"// 图片的链接,非必须}}// 失败返回{"errno":1,// 只要不等于 0 就行"message":"失败信息"}

我的是通过

customInsert

自定义返回类型

// 编辑器配置const editableOption ={config:{placeholder:"请在这里输入内容...",MENU_CONF:{// 配置默认字号// 配置上传图片uploadImage:{// 请求路径server:"api/sysUser/uploadImg",// 后端接收的文件名称fieldName:"file",maxFileSize:1*1024*1024,// 1M// 上传的图片类型allowedFileTypes:["image/*"],// 小于该值就插入 base64 格式(而不上传),默认为 0base64LimitSize: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 参数中,默认 falsemetaWithUrl: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} 上传出错`)},}}}}

测试结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hh8k4mhB-1663476493754)(image/9、图片上传.png)]

5.4、视频上传

目前没有搞过,以后研究

6、上传附件插件使用

官方插件地址:https://github.com/wangeditor-team/wangEditor-plugin-upload-attachment

6.1、下载依赖

  1. 安装yarnnpm install --global yarn# 检查是否成功yarn --version
  2. 安装插件依赖> 这是官网指定的,里面同时也包含了> > wangeditor5> > 的全套依赖,使用的是yarn进行管理> > [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cMCaKgfA-1663476493755)(image/10、yarn'.png)]yarn add @wangeditor/plugin-upload-attachment跟着上面步骤走的就通过下面的方式获取到(原先已近下载了其他依赖)npm i @wangeditor/plugin-upload-attachment -s
  3. 查看在这里插入图片描述

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)

在app.vue里面就能实现一次的注册

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p7bSA52j-1663476493755)(image/14、注册按钮.png)]

6.4、编辑器配置上传附件菜单

注意:如果在

useWangEditor

处理后的

editable

使用也需要在

editableOptionconfig.MENU_CONF.uploadAttachment

的空对象

我是一类ElementUI的消息提示组件,如果复制那一段可能编译报错,自己修改

// 编辑器配置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'],// “上传附件”菜单},}}

方式二

uploadAttachment

就是附件的key

const toolbarOption ={config:{// 插入哪些菜单toolbarKeys:["fontSize",'header1','header2','header3','header4','|','blockquote',"code","codeBlock",'uploadAttachment','|',....]}}

6.6、后端数据响应格式

成功

{"errno":0,"data":{"url":"附件的下载链接"}}

失败

{"errno":1,"message":"错误信息"}

编辑器响应插入的标签

<adata-w-e-type="attachment"data-w-e-is-voiddata-w-e-is-inlinehref="https://xxx.com/aaa/bbb/xxx.zip"download="xxx.zip">xxx.zip</a>

6.7、上传附件测试

需要自己编辑后端接口,并启动按照响应格式返回(文件会直接下载,图片打开一个新的窗口查看,再自行按需保存)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dEuVFFKc-1663476493756)(image/13、上传附件.png)]

点击附件出现内容的关键是

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:''})....// 表单提交functionsubmit(){// 强制同步 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
版权归原作者 小钟要学习!!! 所有, 如有侵权,请联系我们删除。

“wangeditor5在vue3中的全使用过程(图片上传、附件上传、工具栏配置、编辑器配置)”的评论:

还没有评论