<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: