您现在的位置是:首页 >其他 >vue wangeditor富文本编辑器使用网站首页其他

vue wangeditor富文本编辑器使用

Ann_R 2023-05-26 04:00:02
简介vue wangeditor富文本编辑器使用

先安装

npm install wangeditor

代码参考:

  1. MyEditor.vue
<template>
  <div>
    <div style="border: 1px solid #ccc; margin-top: 10px">
      <!-- 工具栏 -->
      <Toolbar style="border-bottom: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig" />
      <!-- 编辑器 -->
      <Editor style="height: 175px; overflow-y: hidden" :defaultConfig="editorConfig" v-model="html" @onChange="onChange"
        @onCreated="onCreated" />
    </div>
  </div>
</template>
 
<script>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
export default {
  name: "MyEditor",
  components: { Editor, Toolbar },
  props: {
    wangType:'',
    aaaId: '',
    bbbId: '',
  },
  data() {
    return {
      editor: null,
      html: "",

      content: {
        type: String,
        default: '',
      },
      toolbarConfig: {
        /* 显示哪些菜单,如何排序、分组 */
        toolbarKeys: [
          "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: ["uploadImage"]
            // 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"
        ]

        // excludeKeys: [ ], /* 隐藏哪些菜单 */ 
      },

      editorConfig: {
        placeholder: "",
        // autoFocus: false,
        readOnly: false, // true只读、不可编辑
        // 所有的菜单配置,都要在 MENU_CONF 属性下
        MENU_CONF: {
          uploadImage: {
            // 后端上传地址,必填
            server: this.$store.state.updataurl,
            // form-data fieldName,后端接口参数名称,默认值wangeditor-uploaded-image
            // fieldName: "file",
            // 1M,单个文件的最大体积限制,默认为 2M
            maxFileSize: 1 * 1024 * 1024,
            // 最多可上传几个文件,默认为 100
            maxNumberOfFiles: 10,
            // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
            allowedFileTypes: ['image/*'],
            // 15 秒,超时时间,默认为 10 秒
            timeout: 15 * 1000,
            // 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
            // meta: {
            //     token: 'xxx',
            //     otherKey: 'yyy'
            // },
            // 将 meta 拼接到 url 参数中,默认 false
            // metaWithUrl: false,
            // 自定义增加 http  header
            headers: {
              Authorization: this.$store.getters.token  || localStorage.getItem("token"),
              // soloFileName: 'article' //和后端协商的图片标识
            },
            uploadImgHeaders: {
              'Access-Control-Allow-Origin': 'origin'
            },
            // withCredentials:true,
            // 自定义上传
            // async customUpload(file, insertFn) {  // JS 语法
            //   const res = await API.Comm.upload(file)
            //   let resultUrl = this.$store.state.baseurl + res.response.data.src;
            //   insertFn(resultUrl)
            //   // insertFn(url, alt, href)
            // }
            // uploadImgHooks:{ //customInsert
            //插入图片的主要方法!!!!
            customInsert: (result, insertImg, editor) => {
              // 图片上传成功,插入图片的回调
              //result为上传图片成功的时候返回的数据
              let url = this.$store.state.baseurl + result.data.src;
              insertImg(url);
            }
            // }
          },
        },
      }
    }
  },
  methods: {
    onCreated(editor) {
      this.editor = Object.seal(editor); // 【注意】一定要用 Object.seal() 否则会报错
    },

    onChange(editor) {          
      this.$emit('catchData', editor.getHtml());
    },
    getEditorText() {
      const editor = this.editor;
      if (editor == null) return;
      // console.log(editor.getText()); // 执行 editor API
    },
    printEditorHtml() {
      const editor = this.editor;
      if (editor == null) return;
      // console.log(editor.getHtml()); // 执行 editor API
    },
    async getContent() {
    	//因为多个地方用到了该控件,所以在富文本编辑器内进行了异步区分,从而执行哪个异步方法
      if(this.wangType=='aaa'){
        if(this.aaaId){
          const res = await this.$API.AsyncFile.getContentByAAAId(this.aaaId)
          this.content = res.data.data.content
        }else{
          this.content = ''
        }
      }else if(this.wangType=='bbb'){
        if(this.bbbId){
          const res = await this.$API.AsyncFile.getContentByBBBId(this.bbbId)
          this.content = res.data.data.content
        }else{
          this.content = ''
        }
      }
      if (this.content) {
      	//图片替换
        this.html = this.content.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, p1) => {
          return `<img src='${p1.indexOf('http') > -1 ? p1 : 'http://xxxxxxxxxx.com.cn/' + p1}' />`
        })
      }
      // console.log("this.html", this.html)
    },
  },
  mounted() {
    // 模拟 ajax 请求,异步渲染编辑器
    this.getContent()
  },

  beforeDestroy() {
    const editor = this.editor;
    if (editor == null) return;
    editor.destroy(); // 组件销毁时,及时销毁 editor ,重要!!!
  }


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

2.test.vue

<template>
  <div class="body">
    <span>测试</span>
    <span>正文</span>
    <my-editor @catchData="catchData" :aaaId='aaaId' :wangType="wangType"></my-editor>
  </div>
</template>

<script>
import MyEditor from '@/components/MyEditor'
export default {
  components: {
    MyEditor
  },
  data() {
    return {
      aaaId: '',
      wangType: 'aaa',
      content:''
    }
  },
  
  methods: {
    catchData(html) {
      this.content = html.replace('<img src="http://xxxxxxxxxx.com.cn/', '<img src="');
      // console.log("catchData---html", html)
    },
  }
}
</script>

<style lang="less" scoped>

</style>

3.store文件夹下的index.js

import Vue from 'vue'
import Vuex from 'vuex'
import tab from './tab'
import user from './user'

import getters from './getters'


Vue.use(Vuex)

export default new Vuex.Store({
  modules:{
    tab,
    user
  },
  state: {
    MAX_NUM:9999,
    baseurl: "http://xxxxxxxxxx.com.cn/",  //图片前缀
    updataurl:"http://xxxxx/uploadPic", //图片上传地址
    videoUploadUrl:"http://xxxx/uploadVideo", //视频上传地址
  },
  getters
})

使用富文本编辑器的时候直接将获取的正文内容传了过去,但每次获取到都是空,后来就直接在富文本编辑器里异步获取到正文内容,数据进行了显示,详情请参考以下链接:

参考:
vue使用wangEditor(富文本编辑器)时,异步获取数据,后端返回数据无法显示问题(已解决)

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。