Vue使用wangEditor 5富文本编辑器步骤及可能遇到的问题

 更新时间:2025年09月06日 15:44:04   作者:夏う沫  
在数字化的今天,无论是内容创作还是日常办公,一款强大易用的富文本编辑器都是必不可少的工具,wangEditor 5正是这样的一款开源编辑器,这篇文章主要介绍了Vue使用wangEditor 5富文本编辑器步骤及可能遇到问题的相关资料,需要的朋友可以参考下

安装

yarn add @wangeditor/editor
# 或者 npm install @wangeditor/editor --save

yarn add @wangeditor/editor-for-vue@next
# 或者 npm install @wangeditor/editor-for-vue@next --save

官网:用于 Vue React | wangEditor

使用

1. 在script中引入css样式和组件

import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue' //引入组件

2. 在template中使用组件

<template>
    <div style="border: 1px solid #ccc">
      <!-- 工具栏 -->
      <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        mode="default"
      />
      <!-- 编辑器 -->
      <Editor
        style="height: 500px; overflow-y: hidden;"
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        mode="default"
        @onCreated="handleCreated"
      />
    </div>
</template>

3. 初始化编辑器

// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef()

// 内容 HTML
const valueHtml = ref('<p>hello</p>')

// 工具栏配置
const toolbarConfig = {}
// 编辑器配置
const editorConfig = { placeholder: '请输入内容...' }

const handleCreated = (editor) => {
    editorRef.value = editor // 记录 editor 实例,重要!
}

// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});

使用效果

4. 工具栏配置

// 工具栏配置
const toolbarConfig = {
  // 隐藏全屏、视频
  excludeKeys: ['fullScreen', 'group-video']
};

5. 编辑器配置

// 编辑器配置
const editorConfig = {
  placeholder: '请输入内容...',
  // 能否编辑
  readOnly: true,
  // 菜单设置
  MENU_CONF: {
    // 上传图片设置
    uploadImage: {
      // 自定义插入图片
      async customUpload(file: File, insertFn) {
        try {
          let formData = new FormData();
          formData.append('file', file);

          //获取上传图片地址
          const data = await postFileUpload(formData);
          // 从 res 中找到 url alt href ,然后插入图片
          insertFn(data, '', data);
        } catch (error) {
          console.log(error);
        }
      },
    },
  },
};

使用过程中的问题

1. 获取工具栏的key值

官网教程获取工具的key,说是toolbar.getConfig().toolbarKeys

但是我通过打印editorRef.value.getConfig().toolbarKeys,却是undefined

最后是通过检查html元素查到的key值

2. 全局样式覆盖,导致编辑器内容样式失效

项目中有给h1、h2、h3、h4....等元素设置默认font-size font-weight

在项目中单独设置font-size:initial font-weight:initial,都不生效

最后是赋值font-size:revert font-weight:revert,才解决

revert表示恢复为浏览器默认值

h1 {
  font-size: 2em;
  font-weight: revert; /* 恢复为浏览器默认字体粗细 */
}
h2,
h3,
h4,
h5,
h6,
p {
  font-size: revert; /* 恢复为浏览器默认字体大小 */
  font-weight: revert; /* 恢复为浏览器默认字体粗细 */
}

ul {
  list-style-type: disc;
}

完整文件

<template>
  <div class="rizhi">
    <div style="padding: 5px">
      <a-button
        style="margin: 0 5px"
        type="primary"
        :loading="saveLoading"
        @click="onSave"
        v-if="isEdit"
        >
        保存
      </a-button>
      <a-button
        style="margin: 0 5px"
        type="primary"
        @click="onEdit"
        v-else-if="!isEdit"
        >
        编辑
      </a-button>
    </div>
    <div class="edit">
      <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        mode="default"
        />
      <Editor
        :style="{ height: tabViewContentHeight + 'px' }"
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        mode="default"
        @onCreated="handleCreated"
        />
    </div>
  </div>
</template>
<script lang="tsx">
  export default {
    name: 'xxxx',
  };
</script>
<script lang="tsx" setup>
  import '@wangeditor/editor/dist/css/style.css'; // 引入 css
  import { computed, onMounted, onBeforeUnmount, ref, shallowRef } from 'vue';
  import { Editor, Toolbar } from '@wangeditor/editor-for-vue';

  // 判断是保存还是编辑
  const isEdit = ref(false);

  // 编辑器实例,必须用 shallowRef
  const editorRef = shallowRef();

  // 内容 HTML
  const valueHtml = ref('');

  // 工具栏配置
  const toolbarConfig = {
    excludeKeys: ['fullScreen', 'group-video'],
  };

  // 编辑器配置
  const editorConfig = {
    placeholder: '请输入内容...',
    readOnly: true,
    MENU_CONF: {
      uploadImage: {
        // 自定义插入图片
        async customUpload(file: File, insertFn) {
          try {
            let formData = new FormData();
            formData.append('file', file);
            
            const data = 	'/xx/xx'		//await 上传图片接口(formData);
            // 从 res 中找到 url alt href ,然后插入图片
            insertFn(data, '', data);

            // 上传图片后,得保存
            imageList1.push(data);
          } catch (error) {
            console.log(error);
          }
        },
      },
    },
  };

  // 初始化编辑器
  const handleCreated = (editor) => {
    editorRef.value = editor; // 记录 editor 实例,重要!
  };

  // 保存
  const saveLoading = ref(false);

  // 初始图片
  let imageList1: any = [];
  // 修改后图片
  let imageList2: any = [];
  const onSave = async () => {
    try {
      saveLoading.value = true;

      let deleteImageList: any = [];
      // 保存时先删除图片
      imageList2 = editorRef.value.getElemsByType('image').map((item) => item.src);

      imageList1.forEach((item) => {
        if (!imageList2.includes(item)) {
          deleteImageList.push(item);
        }
      });

      if (deleteImageList.length !== 0) {
        // 删除图片接口
        //await 删除图片接口();
      }

      // 再保存
      //await 保存接口();
      //await 刷新接口();
      
      editorRef.value.disable();
      isEdit.value = false;
      messageSucc('保存成功');
    } catch (error) {}

    saveLoading.value = false;
  };

  const onEdit = () => {
    isEdit.value = true;
    editorRef.value.enable();
  };

//获取远程数据
  const getList = async () => {
    try {
      const res = ''	//await 获取数据接口();
      valueHtml.value = res.updateExplanation;

      setTimeout(() => {
        // 获取初始图片
        imageList1 = editorRef.value.getElemsByType('image').map((item) => item.src);
      }, 0);
    } catch (error) {}
  };

  onMounted(async () => {
    await getList();
  });

  // 组件销毁时,也及时销毁编辑器
  onBeforeUnmount(() => {
    const editor = editorRef.value;
    if (editor == null) return;
    editor.destroy();
  });
</script>

<style lang="less" scoped>
  .rizhi {
    background-color: #fff;
    display: flex;
    flex-direction: column;
    .rizhiHtml {
      border: 1px solid #ccc;
      overflow-y: scroll;
      padding: 5px;
      flex: 1;
    }

    .edit {
      border: 1px solid #ccc;
    }
  }

  :deep(.w-e-text-container) {
    h1 {
      font-size: 2em;
      font-weight: revert; /* 恢复为浏览器默认字体粗细 */
    }
    h2,
    h3,
    h4,
    h5,
    h6,
    p {
      font-size: revert; /* 恢复为浏览器默认字体大小 */
      font-weight: revert; /* 恢复为浏览器默认字体粗细 */
    }

    ul {
      list-style-type: disc;
    }
  }
</style>

总结 

到此这篇关于Vue使用wangEditor 5富文本编辑器步骤及可能遇到的问题的文章就介绍到这了,更多相关Vue使用wangEditor5富文本编辑器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • uniapp+Vue实现App端用户每日弹出签到弹窗功能

    uniapp+Vue实现App端用户每日弹出签到弹窗功能

    用户签到这个功能是很多APP、小程序等都具备的,也是其成长体系中的重要环节,这篇文章主要介绍了uniapp+Vue实现App端用户每日弹出签到弹窗功能的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2026-05-05
  • Vue + Element-ui的下拉框el-select获取额外参数详解

    Vue + Element-ui的下拉框el-select获取额外参数详解

    这篇文章主要介绍了Vue + Element-ui的下拉框el-select获取额外参数详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vue循环中调用接口-promise.all();按顺序执行异步处理方式

    vue循环中调用接口-promise.all();按顺序执行异步处理方式

    这篇文章主要介绍了vue循环中调用接口-promise.all();按顺序执行异步处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Vue解决ajax跨域的问题

    Vue解决ajax跨域的问题

    这篇文章主要介绍了Vue解决ajax跨域的问题,跨域请求:是指协议名、主机名、端口号三者有任何一个不一样,而且跨域请求是请求发出去了,服务器接收并返回了结果,只是浏览器没有接收响应结果。感兴趣的同学可以参考阅读
    2023-04-04
  • vant之关于van-list的使用以及一些坑的解决方案

    vant之关于van-list的使用以及一些坑的解决方案

    这篇文章主要介绍了vant之关于van-list的使用以及一些坑的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • 详解Vue计算属性原理

    详解Vue计算属性原理

    计算属性是Vue中比较好用的API,开发者可以利用计算属将复杂的计算进行缓存,同时基于它的响应式特性,我们无需关注数据更新问题,但需要注意的是,计算属性是惰性求值的,本文将详细介绍计算属性的实现原理,需要的朋友可以参考下
    2023-05-05
  • vuex实现的简单购物车功能示例

    vuex实现的简单购物车功能示例

    这篇文章主要介绍了vuex实现的简单购物车功能,结合实例形式分析了vuex购物车组件相关商品列表、购物车创建、添加、删除、清空等相关操作技巧,需要的朋友可以参考下
    2019-02-02
  • 基于vuex实现购物车功能

    基于vuex实现购物车功能

    这篇文章主要为大家详细介绍了基于vuex实现购物车功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-01-01
  • 解决vue路由发生了跳转但是界面没有任何反应问题

    解决vue路由发生了跳转但是界面没有任何反应问题

    这篇文章主要介绍了解决vue路由发生了跳转但是界面没有任何反应问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • vue-cli 3.0 引入mint-ui报错问题及解决

    vue-cli 3.0 引入mint-ui报错问题及解决

    这篇文章主要介绍了vue-cli 3.0 引入mint-ui报错问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05

最新评论