vue 中 wangeditor5 双向绑定自定义上传图片

1,186 阅读2分钟

基于业务由于我们的中台是要商品详情设置多个富文本数据也是循环出来的,一开始在使用ue 百度的富文本编辑器后出现了各种错误的情况,多个富文本展示样式等等,就放弃了百度ue 富文本由于,听说百度ue 最后一次pr 代码是19年。 在种种挑选中选择了wangeditor。对比过tm ckeditor 还有等等几个编辑器发现 wangeditor 对于react 跟vue 的支持很高,于是考虑到vue 的适配最终选择了wangeditor5

wangeidor 地址:www.wangeditor.com/

首先安装依赖这里是vue2 版本 vue3 版本没啥大区别无非是hooks 的写法。这里不做展示

yarn add @wangeditor/editor-for-vue

yarn add @wangeditor

  <div>
    <div>
      <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editor"
        :defaultConfig="toolbarConfig"
        :mode="mode"
      />
      <Editor
        style="height: 400px; overflow-y: hidden"
        v-model="values"
        :defaultConfig="editorConfig"
        :mode="mode"
        @onCreated="onCreated"
        @onChange="onChange"
      />
    </div>
  </div>
</template>

<script>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import axios from "axios";
export default {
  components: { Editor, Toolbar },
  props: {
    values: "",
  },
  data() {
    return {
      editor: null,
      html: "",
      // 工具栏配置详情参考官网
      toolbarConfig: {
        excludeKeys: "fullScreen",
      },
       // 编辑器配置详情参考官网
      editorConfig: {
        placeholder: "请输入内容...",
        MENU_CONF: {
          uploadImage: {
            // 用户自定义上传图片
            customUpload(file, insertFn) {
              let data = new FormData();
              data.append("file", file); //file为上传文件返回的所有file
              let config = {
                method: "post",
                url:
                  location.origin +
                  process.env.VUE_APP_BASE_API +
                  "XXXX", //上传图片的地址
                headers: {
                  "Content-Type": "multipart/form-data",
                  token: localStorage.getItem("token"),
                },
                data: data,
              };

              let that = this;
              axios(config)
                .then((res) => {
                  if (res && res.data.code === 500) {
                    alert(res.data.msg);
                  }
                  let url = res.data.data; //服务器上的图片路径
                  insertFn(url, "使用说明", url); //插入图片(使用的wangEditor插件)
                })
                .catch((error) => {
                  console.log(error);
                });
            },

            onBeforeUpload(file) {
              // file 选中的文件,格式如 { key: file }
              return file;

              // 可以 return
              // 1. return file 或者 new 一个 file ,接下来将上传
              // 2. return false ,不上传这个 file
            },
            // 上传进度的回调函数
            onProgress(progress) {
              // progress 是 0-100 的数字
              console.log("progress", progress);
            },
            // 单个文件上传成功之后
            onSuccess(file, res) {
              console.log(`${file.name} 上传成功`, res);
            },
            // 单个文件上传失败
            onFailed(file, res) {
              console.log(`${file.name} 上传失败`, res);
            },
            // 上传错误,或者触发 timeout 超时
            onError(file, err, res) {
              this.$message.error(err);
              console.log(`${file.name} 上传出错`, err, res);
            },
          },
        },
      },
      mode: "default", // or 'simple'
    };
  },
  methods: {
    onCreated(editor) {
      this.editor = Object.seal(editor); // 一定要用 Object.seal() ,否则会报错
    },
    onChange(editor) {
      this.$emit("update:values", editor.getHtml());
    },
  },
  mounted() {
    console.log(this.editorConfig);
  },
  beforeDestroy() {
    const editor = this.editor;
    if (editor == null) return;
    editor.destroy(); // 组件销毁时,及时销毁编辑器
  },
};
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>

<editorBar :values.sync="it.itemDetail" v-if="!isShowInfo"></editorBar>
值得注意的是vue 或者 react 中不要在你调用的页面直接写多个editor 代码块会导致重复创建富文本的工具栏报错会出现渲染问题。封装成组件调用则不会出现重复创建工具栏问题
组件调用 v-model 双向绑定数据
当然了也可以动态创建多个富文本如官网例子:
<div>
  <div id="toolbar-container-1"></div>
  <div id="editor-container-1"></div>
</div>

<hr>

<div>
  <div id="toolbar-container-2"></div>
  <div id="editor-container-2"></div>
</div>
// 创建编辑器1
const editor1 = createEditor({
  selector: '#editor-container-1',
  mode: 'default'
})
// 创建工具栏1
const toolbar1 = createToolbar({
  editor: editor1,
  selector: '#toolbar-container-1',
  mode: 'default'
})

// 创建编辑器2
const editor2 = createEditor({
  selector: '#editor-container-2',
  mode: 'simple'
})
// 创建工具栏2
const toolbar2 = createToolbar({
  editor: editor2,
  selector: '#toolbar-container-2',
  mode: 'simple'
})

最后就实现了vue 的双向数据绑定及自定义上传代码,没啥难度就是看着文档找了半天搞定了需要的小伙伴自己copy 代码,最后的最后呢为什么要用自定义上传方法是因为官放提供的方法你的接口格需要按照要求,返回参数需要一致才可以