SoFunction
Updated on 2025-04-12

vue-quill-editor secondary encapsulation, implement custom file upload method

Implementation steps

  • First introduce the vue-quill-editor component, customize the configuration, and add the upload operation in the custom configuration. However, since the vue-quill-editor component does not support file upload, this operation is invalid and the logic needs to be implemented by yourself.
  • Customize the css style, file upload icon, size, etc. for added upload button
  • Simulate the upload click event. In the editor configuration, there is a handler object to handle custom upload clicks.
  • After clicking, we will ask it to trigger the upload operation of the file upload component in element-ui, so we put the el-upload component on the page, and then hide it with css. When clicking the upload icon in rich text, we simulate clicking el-upload, and the upload file operation box will pop up.
  • Then customize the upload method of el-upload, call your own interface in the uploaded callback, and get a file path string
  • Then insert this string into rich text through a quill object, that is, the parent object that the vue-quill-editor component depends on. The link in a link is implemented by inheriting the create method in the parent class.
  • If you don't understand, you can read the comments in the code

Complete code

1. Quill-editor-upload custom component

<template>
  <div>
    <quill-editor ref="quillEditor" :options="editorOption" :content="content" @change="onEditorChange($event)"
      @blur="$emit('blur')"></quill-editor>
    <!-- Hiddenupload -->
    <el-upload class="uploadFile" drag action="#" :http-request="uploadFile" :limit="1" :on-exceed="handleExceed"
      :on-remove="handleRemove" :file-list="fileList">
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">
        Drag the file here,or<em>Click to upload</em>
      </div>
    </el-upload>
  </div>
</template>
<script>
import Quill from 'quill';
import { quillEditor } from "vue-quill-editor";
import "quill/dist/";
import "quill/dist/";
import "quill/dist/";
import { editorUploadPath } from "@/api/excel/";
 
// Toolbar configurationconst toolbarOptions = [
  ['bold', 'italic', 'underline', 'strike'],        // toggled buttons
  ['blockquote', 'code-block'],
 
  [{ 'header': 1 }, { 'header': 2 }],               // custom button values
  [{ 'list': 'ordered' }, { 'list': 'bullet' }],
  [{ 'script': 'sub' }, { 'script': 'super' }],      // superscript/subscript
  [{ 'indent': '-1' }, { 'indent': '+1' }],          // outdent/indent
  [{ 'direction': 'rtl' }],                         // text direction
 
  [{ 'size': ['small', false, 'large', 'huge'] }],  // custom dropdown
  [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
 
  [{ 'color': [] }, { 'background': [] }],          // dropdown with defaults from theme
  [{ 'font': [] }],
  [{ 'align': [] }],
  ['link', 'image', 'video', 'upload'],
  ['clean']                                         // remove formatting button
]
 
// Custom insert a linkvar Link = ('formats/link');
class FileBlot extends Link {  // Inherit Link Blot  static create(value) {
    let node = undefined
    if (value && !) {  // Adapt to the original Link Blot      node = (value);
    }
    else {  // Custom Link Blot      node = ();
      ('download', );  // Left click to download       = ;
       = ;
    }
    return node;
  }
}
 = 'link';
 = 'A';
(FileBlot);
 
export default {
  name: "quill-editor-upload",
  components: { quillEditor },
  // Custom v-model, prop is a property in props, representing the value passed in v-model; event represents the event name that is output to v-model in reverse  model: {
    prop: 'content',
    event: 'changeContent'
  },
  // Customize the value passed in v-model  props: {
    content: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      fileList: [], // File list      // editor configuration      editorOption: {
        placeholder: 'Please enter the text...',
        modules: {
          toolbar: {
            container: toolbarOptions,  // Toolbar            handlers: {
              // Simulate the upload button click event              'upload': (value => {
                if (value) {
                  ('.uploadFile input').click()
                }
              })
            }
          }
        }
      }
    }
  },
  methods: {
    // Custom v-model, pass out the html provided by the editor selector change event    onEditorChange(e) {
      this.$emit('changeContent', )
    },
    // Custom file upload    uploadFile(res) {
      // ('Upload successfully', res);      let myFormData = new FormData();
      ("file", );
      editorUploadPath(myFormData).then((response) => {
        if ( === 0) {
          let fileNameLength = 
          // Insert link          let quill = this.$
          let length = ().index;
          (length, 'link', { href: , innerText:  }, "api")
          (length + fileNameLength)
           = []
        }
      });
    },
    // Prompt for file exceeding limit    handleExceed() {
      this.$(`Current limit selection 1 A file,Please delete it and update it!`);
    },
    // Remove file    handleRemove() {
       = [];
    },
  }
}
</script>
<style scoped>
/* File upload icon style */
/deep/ .quill-editor .-toolbar .ql-formats .ql-upload {
  background: url("../assets/");
  background-size: 16px 16px;
  background-position: center center;
  background-repeat: no-repeat;
}
 
/* Hide upload and trigger with simulated events */
.uploadFile {
  width: 0;
  height: 0;
  display: none;
}
</style>

2. Use this component

<el-form-item label="content" prop="content">
    <quillEditorUpload v-model=""></quillEditorUpload>
</el-form-item>

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.