vue2使用wangEditorV5富文本编辑器

一  介绍

wangEditor5 - 开源 Web 富文本编辑器,开箱即用,配置简单。2022.04.11 正式发布 v5 版本

官网地址:wangEditor

二  使用

1.安装

支持vue2、vue3、react多框架,这里只介绍vue2使用

npm install @wangeditor/editor --save
npm install @wangeditor/editor-for-vue --save

2.引入模板、script、style文件

模板

<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"
        />
    </div>
</template>

script

<script>
import Vue from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'

export default Vue.extend({
    components: { Editor, Toolbar },
    data() {
        return {
            editor: null,
            html: '<p>hello</p>',
            toolbarConfig: { },
            editorConfig: { placeholder: '请输入内容...' },
            mode: 'default', // or 'simple'
        }
    },
    methods: {
        onCreated(editor) {
            this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
        },
    },
    mounted() {
        // 模拟 ajax 请求,异步渲染编辑器
        setTimeout(() => {
            this.html = '<p>模拟 Ajax 异步设置内容 HTML</p>'
        }, 1500)
    },
    beforeDestroy() {
        const editor = this.editor
        if (editor == null) return
        editor.destroy() // 组件销毁时,及时销毁编辑器
    }
})
</script>

style

<style src="@wangeditor/editor/dist/css/style.css"></style>

3.配置工具、菜单栏

查看工具栏配置

 console.log(this.editor.getConfig());

 const toolbar = DomEditor.getToolbar(this.editor)

 const curToolbarConfig = toolbar.getConfig()

 console.log( curToolbarConfig.toolbarKeys ) // 排序和分组

工具栏配置

// 工具栏配置(注意结构,否则不起作用)

      toolbarConfig: {

        excludeKeys :[

          'todo',

          'codeBlock'

        ]

      },

查看菜单栏配置

console.log(this.editor.getConfig())

菜单栏配置

// 菜单配置(注意结构,否则不起作用)

      editorConfig: {

        placeholder: "请输入内容...",

        MENU_CONF: {

          uploadImage: {

            // 自定义上传图片 方法

            customUpload: this.uploadImg,

            // 上传接口设置文件名

            fieldName: "file",

            meta: {

              token: getToken(),

            },

          },

          uploadVideo: {

            customUpload: this.uploadVideo,

            fieldName: "file",

            meta: {

              token: getToken(),

            },

          },

        },

      },

注:可以通过打印this.editor对象获取对象上的全部方法再找到自己需要使用的。

三  关于绑定问题

1.组件 v-model 绑定数据会默认使用 value 的prop和名为 input 的事件,可以粗浅的理解为 v-model="html" 等效于 v-bind:value="html" + v-on:input="(e) => { this.html = e.target.value }"

2.封装组件

  • 在自定义组件中:
    • 我们需要在 props 中定义一个 value 来接受父组件传入的值
    • 然后我们需要使用 $emit('input', newValue) 将新值发送给父组件
  • 在父组件中:
    • 使用 v-model 进行双向绑定

四  代码

editor组件

<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"
      @onChange="onChange"
      @onCreated="onCreated"
    />
  </div>
</template>
 
<script>
import Vue from "vue";
import axios from "axios";
import { getToken } from "@/utils/auth";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
export default Vue.extend({
  components: { Editor, Toolbar },
  data() {
    return {
      editor: null,
      html: "<p></p>",
      currentValue:'',
      // 工具栏配置(注意结构,否则不起作用)
      toolbarConfig: {
        excludeKeys :[
          'todo',
          'codeBlock'
        ]
      },
      // 菜单配置(注意结构,否则不起作用)
      editorConfig: {
        placeholder: "请输入内容...",
        MENU_CONF: {
          uploadImage: {
            // 自定义上传图片 方法
            customUpload: this.uploadImg,
            // 上传接口设置文件名
            fieldName: "file",
            meta: {
              token: getToken(),
            },
          },
          uploadVideo: {
            customUpload: this.uploadVideo,
            fieldName: "file",
            meta: {
              token: getToken(),
            },
          },
        },
      },
      mode: "default", // or 'simple'
      // 图片、视频上传服务器地址
      uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload",
    };
  },
   props: {
    /* 编辑器的内容 */
    value: {
      type: String,
      default: "",
    },
    /* 高度 */
    height: {
      type: Number,
      default: null,
    },
    /* 最小高度 */
    minHeight: {
      type: Number,
      default: null,
    },
    /* 只读 */
    readOnly: {
      type: Boolean,
      default: false,
    },
    // 上传文件大小限制(MB)
    fileSize: {
      type: Number,
      default: 5,
    },
    /* 类型(base64格式、url格式) */
    type: {
      type: String,
      default: "url",
    },
  },
  watch: {
    // 监听父组件中editor值的变化
    value: {
      handler(val) {
        this.html=val
        this.currentValue=val
      },
      immediate: true,
    },
  },
  mounted() {
    this.initEditor();
  },
  methods: {
    onCreated(editor) {
       // 一定要用 Object.seal() ,否则会报错
      this.editor = Object.seal(editor);
    },
    onChange(editor){
      // this.$emit("change", this.html);
      // this.value=this.html
       this.$emit('input', this.html)
    },
    //自定义上传视频
    uploadVideo(file, insertFn) {
      let imgData = new FormData();
      imgData.append("file", file);
      axios({
        url: this.uploadFileUrl,
        data: imgData,
        method: "post",
        headers: {
          Authorization: "Bearer " + getToken(),
        },
      }).then((response) => {
        if (response.data.code === 200) {
          // 插入后端返回的url,将图片显示在页面上
          insertFn(response.data.url);
          this.$message({
            type: "success",
            message: "上传成功",
          });
        } else {
        }
      });
    },
    //自定义上传图片
    uploadImg(file, insertFn) {
      let imgData = new FormData();
      imgData.append("file", file);
      axios({
        url: this.uploadFileUrl,
        data: imgData,
        method: "post",
        headers: {
          Authorization: "Bearer " + getToken(),
        },
      }).then((response) => {
        if (response.data.code === 200) {
          // 插入后端返回的url
          insertFn(response.data.url);
          this.$message({
            type: "success",
            message: "上传成功",
          });
        } else {
        }
      });
    },
  },
  mounted() {
    // 模拟 ajax 请求,异步渲染编辑器
    setTimeout(() => {
      if(this.currentValue){
        this.html=this.currentValue
      }
      // 查看菜单配置项
      // console.log(this.editor.getConfig());
      // const toolbar = DomEditor.getToolbar(this.editor)
      // const curToolbarConfig = toolbar.getConfig()
      // console.log( curToolbarConfig.toolbarKeys ) // 当前菜单排序和分组
    }, 1500);
  },
  beforeDestroy() {
    const editor = this.editor;
    if (editor == null) return;
    editor.destroy(); // 组件销毁时,及时销毁编辑器
  },
});
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>

父组件

<template>
  <div id="app">
    <wang-editor :option="option" v-model="html"></wang-editor>
  </div>
</template>

<script>
import WangEditor from './components/wang-editor.vue'

export default {
  name: 'App',
  components: {
    WangEditor
  },
  data() {
    return {
      option: {
        height: 500
      },
      html: '<p></p>'
    }
  },
}
</script>

五  补充:

富文本框默认字体大小修改:

<style>
.w-e-text-container{
  font-size: 19px!important;
}
</style>

可利用开发者工具找到富文本框文字展示的类名,另写样式覆盖默认sytle文件中默认样式即可。

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值