Rebuilding Vue kill editor: upload pictures to server and insert rich text

Keywords: Vue Attribute Database

<template>
  <div>
    <quilleditor v-model="content"
                 ref="myTextEditor"
                 :options="editorOption"
                 @change="onChange"
                 >
      <div id="toolbar" slot="toolbar">
        <select class="ql-size">
          <option value="small"></option>
          <!-- Note a missing, thus falsy value, is used to reset to default -->
          <option selected></option>
          <option value="large"></option>
          <option value="huge"></option>
        </select>
        <!-- Add subscript and superscript buttons -->
        <span class="ql-formats"><button class="ql-script" value="sub"></button></span>
        <span class="ql-formats"><button class="ql-script" value="super"></button></span>
        <span class="ql-formats"><button type="button" class="ql-bold"></button></span>
        <span class="ql-formats"><button type="button" class="ql-italic"></button></span>
        <span class="ql-formats"><button type="button" class="ql-blockquote"></button></span>
        <span class="ql-formats"><button type="button" class="ql-list" value="ordered"></button></span>
        <span class="ql-formats"><button type="button" class="ql-list" value="bullet"></button></span>
        <span class="ql-formats"><button type="button" class="ql-link"></button></span>
        <span class="ql-formats">
        <button type="button" @click="imgClick" style="outline:none">
        <svg viewBox="0 0 18 18"> <rect class="ql-stroke" height="10" width="12" x="3" y="4"></rect> <circle
          class="ql-fill" cx="6" cy="7" r="1"></circle> <polyline class="ql-even ql-fill"
                                                                  points="5 12 5 11 7 9 8 10 11 7 13 9 13 12 5 12"></polyline> </svg>
        </button>
      </span>
        <span class="ql-formats"><button type="button" class="ql-video"></button></span>
      </div>
    </quilleditor>
  </div>
</template>
<script>
  import 'quill/dist/quill.core.css'
  import 'quill/dist/quill.snow.css'
  import 'quill/dist/quill.bubble.css'

  import {quillEditor} from 'vue-quill-editor'

  export default {
    name: "v-editor",
    props: {
      value: {
        type: String
      },
      /*Address for uploading pictures*/
      uploadUrl: {
        type: String,
        default: '/'
      },
      /*name of file control for uploading pictures*/
      fileName: {
        type: String,
        default: 'file'
      },
      maxUploadSize:{
        type:Number,
        default: 1024 * 1024 * 500
      }
    },
    data() {
      return {
        content: '',
        editorOption: {
          modules: {
            toolbar: '#toolbar'
          }
        },
      }
    },
    methods: {
      onChange() {
        this.$emit('input', this.content)
      },
      /*Choose upload picture switch*/
      onFileChange(e) {
        var fileInput = e.target;
        if (fileInput.files.length === 0) {
          return
        }
        this.editor.focus();
        if (fileInput.files[0].size > this.maxUploadSize) {
          this.$alert('Picture cannot be greater than 500 KB', 'Picture size too large', {
            confirmButtonText: 'Determine',
            type: 'warning',
          })
        }
        var data = new FormData;
        data.append(this.fileName, fileInput.files[0]);
        this.$http.post(this.uploadUrl, data)
          .then(res => {
            if (res.data) {
              console.log(res.data);
              this.editor.insertEmbed(this.editor.getSelection().index, 'image', res.data)
            }
          })
      },
      /*Click the upload picture button*/
      imgClick() {
        if (!this.uploadUrl) {
          console.log('no editor uploadUrl');
          return;
        }
        /*Memory creation input file*/
        var input = document.createElement('input');
        input.type = 'file';
        input.name = this.fileName;
        input.accept = 'image/jpeg,image/png,image/jpg,image/gif';
        input.onchange = this.onFileChange;
        input.click()
      }
    },
    computed: {
      editor() {
        return this.$refs.myTextEditor.quill
      }
    },
    components: {
      'quilleditor': quillEditor
    },
    mounted() {
      this.content = this.value
    },
    watch: {
      'value'(newVal, oldVal) {
        if (this.editor) {
          if (newVal !== this.content) {
            this.content = newVal
          }
        }
      },
    }
  }

</script>

Initial editor:

Modified editor:

To remove some redundant functions and upload pictures to the server, the following codes are mainly used:

      /*Choose upload picture switch*/
      onFileChange(e) {
        var fileInput = e.target;
        if (fileInput.files.length === 0) {
          return
        }
        this.editor.focus();
        if (fileInput.files[0].size > this.maxUploadSize) {
          this.$alert('Picture cannot be greater than 500 KB', 'Picture size too large', {
            confirmButtonText: 'Determine',
            type: 'warning',
          })
        }
        var data = new FormData;
        data.append(this.fileName, fileInput.files[0]);
        this.$http.post(this.uploadUrl, data)
          .then(res => {
            if (res.data) {
              console.log(res.data);
              this.editor.insertEmbed(this.editor.getSelection().index, 'image', res.data)
            }
          })
      },
      /*Click the upload picture button*/
      imgClick() {
        if (!this.uploadUrl) {
          console.log('no editor uploadUrl');
          return;
        }
        /*Memory creation input file*/
        var input = document.createElement('input');
        input.type = 'file';
        input.name = this.fileName;
        input.accept = 'image/jpeg,image/png,image/jpg,image/gif';
        input.onchange = this.onFileChange;
        input.click()
      }

After clicking the upload picture button, first call the imgClick method, and when the content changes, call the onFileChange method to upload the picture to the server. The server path is stored in this.uploadUrl and passed in when calling components. Component call:

<v-editor  v-model="text" upload-url="/upload/image" fileName="file"/>

Property Description:

Attribute name Explain data type Default value
value The output of the editor can be bound in two directions with v-model String nothing
upload-url The image upload address corresponding to the upload button is prefixed with the global url configuration of the project String nothing
file-name Parameter name of the uploaded file String file
maxUploadSize Size limit of uploaded file, unit: byte Number 500kb

Remarks:

Default supported image types: jpg/png/jpeg/gif

Test results:

Background database:

Posted by bouba on Thu, 02 Jan 2020 13:14:03 -0800