The method of using wangeditor/editor-for-vue rich text plug-in in vue2 (encapsulation component)

First install wangeditor/editor-for-vue (node version problem plus –legacy-peer-deps, otherwise the installation will not work)

npm install @wangeditor/editor-for-vue –save –legacy-peer-deps

This is the packaged file upload interface

// file upload
  uploadImg: file => {
    const formData = new FormData()
    formData.append('files', file)
    return request({
      url: '/upload/uploadFile',
      method: 'POST',
      data: formData,
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })
  }

Encapsulated component code

<template>
  <div style="border: 1px solid #ccc" class="relative">
    <div v-if="disabled" class="disable-layer" />
    <Toolbar ref="toolbar" style="border-bottom: 1px solid #ccc" :editor="editor" :default-config="toolbarConfig" :mode="mode" />
    <Editor style="overflow-y: hidden" :value="value" :default-config="editorConfig" :mode="mode" @input="handleInput" @onCreated="onCreated" />
  </div>
</template>

<script>
// import package
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
// Interface for uploading files
import { videoApi } from '@/api/video'
// Import the style of wangeditor/editor-for-vue
import '@wangeditor/editor/dist/css/style.css'
// The path prefix of the uploaded file
import { baseUrl } from '@/utils/pictureUrl'
export default {
  name: 'WangEditor',
  components: { Editor, Toolbar },
  props: {
    value: String,
    disabled: Boolean,
    cusHeight: {
      type: String,
      default: '150px'
    }
  },
  data() {
    return {
      editor: null,
      html: '',
      // Configuration of wangeditor/editor-for-vue
      toolbarConfig: {
        toolbarKeys: [
          'bold',
          'underline',
          'italic',
          'through',
          'clearStyle',
          'color',
          'bgColor',
          'fontSize',
          'justifyLeft',
          'justifyRight',
          'justifyCenter',
          'justifyJustify',
          'lineHeight',
          'header1',
          'header2',
          'header3',
          'header4',
          'header5',
          'bulletedList',
          'numberedList',
          'uploadImage'
          // "uploadVideo"
        ]
      },
      editorConfig: {
        placeholder: 'Please enter content...',
        MENU_CONF: {
          uploadImage: {
            // custom image upload
            async customUpload(file, insertFn) {
              videoApi.uploadImg(file).then(response => {
                if (response. result == 1) {
                  const url = baseUrl + response.msg
                  // insert image into textbox
                  insertFn(url)
                }
              })
            }
          }
          // uploadVideo: {
          // // Custom image upload
          // async customUpload(file, insertFn) {
          // uploadFile('', file).then(response => {
          // const url = response.data
          // insertFn(this. $getFilePath(url))
          // })
          // }
          // }
        }
      },
      mode: 'default' // or 'simple'
    }
  },
  mounted() {},
  created() {},
  beforeDestroy() {
    const editor = this.editor
    if (editor == null) return
    editor.destroy() // Destroy the editor in time when the component is destroyed
  },
  methods: {
    onCreated(editor) {
      this.editor = Object.seal(editor) // Be sure to use Object.seal(), otherwise an error will be reported
      // console.log('this.editor :>> ', this.editor.getAllMenuKeys());
    },
    handleInput(value) {
      console. log(value)
      // Pass the text content to the parent component (referencing the vue file of this component)
      this. $emit('input', value)
    }
  }
}
</script>

<style lang="scss" scoped>
.disable-layer {
  width: 100%;
  height: 100%;
  background: #f5f7fa;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 99;
  opacity: 0.5;
}
</style>

Then the mani.js entry file can be registered and used globally

import myEditor from ‘@/components/myEditor/CusWangEditor.vue’

Vue. component(‘myEditor’, myEditor)

<template>
  <div>
    <el-card>
      <myEditor :value="initForm. content" @input="input" />
      <div class="btn"><el-button type="primary" size="small" @click="submit">Save</el-button></div>
    </el-card>
  </div>
</template>

<script>
import { contentApi } from '@/api/content'
export default {
  name: 'Area',
  data() {
    return {
      // search
      postForm: {
        currentPage: 1,
        pageSize: 10
      },
      initForm: {
        content: '',
        plateId: 5,
        id: ''
      }
    }
  },
  computed: {},
  mounted() {
    this. loadData()
  },
  methods: {
    // Store the content text content passed from myEditor rich text
    input(value) {
      this.initForm.content = value
    },
    // save
    submit() {
      this.$confirm('Are you sure to save?', 'Prompt', {
        confirmButtonText: 'OK',
        cancelButtonText: 'Cancel',
        type: 'warning'
      })
        .then(() => {
          contentApi.text(this.$filNull(this.initForm)).then(res => {
            const { result, msg } = res
            if (result == 1) {
              this. $message. success(msg)
            } else {
              this.$message.warning(msg)
            }
          })
        })
        .catch(() => {
          this. $message({
            type: 'info',
            message: 'save canceled'
          })
        })
    },
    // Get the text of area A of the eye valley
    loadData() {
      contentApi.getRichTextContent({ plateId: this.initForm.plateId }).then(res => {
        const { data, result, msg } = res
        if (result == 1) {
          this.initForm.content = data.content
          this.initForm.id = data.id
        } else {
          this.$message.warning(msg)
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.dashboard {
   &-container {
    margin: 30px;
  }
   &-text {
    font-size: 30px;
    line-height: 46px;
  }
}
.btn {
  margin-top: 50px;
  display: flex;
  justify-content: center;
}
::v-deep.ql-container {
  height: 500px !important;
}
</style>

That’s it

The most important thing is the following code

// import package
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
// Interface for uploading files
import { videoApi } from '@/api/video'
// Import the style of wangeditor/editor-for-vue
import '@wangeditor/editor/dist/css/style.css'
// The path prefix of the uploaded file
import { baseUrl } from '@/utils/pictureUrl'
<template>
  <div style="border: 1px solid #ccc" class="relative">
    <div v-if="disabled" class="disable-layer" />
    <Toolbar ref="toolbar" style="border-bottom: 1px solid #ccc" :editor="editor" :default-config="toolbarConfig" :mode="mode" />
    <Editor style="overflow-y: hidden" :value="value" :default-config="editorConfig" :mode="mode" @input="handleInput" @onCreated="onCreated" />
  </div>
</template>
MENU_CONF: {
          uploadImage: {
            // custom image upload
            async customUpload(file, insertFn) {
              // upload image
              videoApi.uploadImg(file).then(response => {
                if (response. result == 1) {
                  const url = baseUrl + response.msg
                  // Insert the picture into the text box (must remember to insertFn into the text box or it won't work)
                  insertFn(url)
                }
              })
            }
          }
          // uploadVideo: {
          // // Custom image upload
          // async customUpload(file, insertFn) {
          // uploadFile('', file).then(response => {
          // const url = response.data
          // insertFn(this. $getFilePath(url))
          // })
          // }
          // }
        }
beforeDestroy() {
    const editor = this.editor
    if (editor == null) return
    editor.destroy() // Destroy the editor in time when the component is destroyed
  },
  methods: {
    onCreated(editor) {
      this.editor = Object.seal(editor) // Be sure to use Object.seal(), otherwise an error will be reported
      // console.log('this.editor :>> ', this.editor.getAllMenuKeys());
    },
    handleInput(value) {
      console. log(value)
      // Pass the text content to the parent component (referencing the vue file of this component)
      this. $emit('input', value)
    }
  }