Ideas: Hijacking the image click event in the rich text configuration. In this event, click the Upload component in elementUI (< el-Upload >) to trigger the operation of the local upload server, hide the Upload component in the text stream, and change the upload server to Qiniuyun. The key and hash in the returned value are stitched together into the image address echo assignment on Qniu Cloud Line to the rich text component. Complete picture uploading and echo functions.

1. Encapsulate rich text components

quill.vue

(1) the template

<template> <! > <div class="editor_wrap"> < el-Upload class="avatar-uploader" action="http://upload-z2.qiniup.com" // // Accepted data :show-file-list="false" // Accepted data :show-file-list="false" // Whether to display a list of uploaded files :on-success=" UploadEditorSuccess ":on-error=" UploadEditorError" : before-Upload ="beforeEditorUpload"> < / el - upload > < el - row v - loading = "quillUpdateImg" > < / / v - loading is upload animation quill - editor: options = "editorOption" / / bind the rich text editor configuration items class="editor" v-model="content" ref="QuillEditor" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" @change="onEditorChange($event)" @ready="onEditorReady($event)"> </quill-editor> </el-row> </div> </template>

(2) the script

<script> import { quillEditor } from 'vue-quill-editor' import 'quill/dist/quill.core.css' import 'quill/dist/quill.snow.css' const toolbarOptions = [ ['bold', 'italic', 'underline', 'strike'], / / bold italics underlined strikethrough - [' bold, italic, 'underline', 'strike'] [' blockquote ', 'code - block']. / / reference code block -- -- -- -- -- [' blockquote ', 'code - block] [{header: 1}, {2} header:], / / 1, level 2 titles - [{header: 1}, {header: 2}] [{the list: 'ordered'}, {list: 'bullet'}], / / orderly and unordered list -- -- -- -- -- [{the list: 'ordered'}, {list: 'bullet'}] [{script: 'sub'}, {script: 'super'}], / / superscript, subscript - [{script: 'sub'}, {script: 'super'}] [{text-indent: '1'}, {text-indent: '+ 1'}], / / indent - [{text-indent: '1'}, {text-indent: '+ 1'}] [{direction: 'RTL}], / / text direction -- -- -- -- -- [{' direction' : 'RTL}] [{size: [' small' false, 'large' and 'huge']}], / / font size -- -- -- -- -- [{size: [' small 'false,' large 'and' huge ']}] [{header: [1, 2, 3, 4, 5, 6, false]}], [{/ / title -- -- -- -- -- the header: [1, 2, 3, 4, 5, 6, false]}] [{color: []}, {background: []}], / / font colors, fonts, background color -- -- -- -- -- [{color: []}, {background: [] [] {the font: []}}], / / font types -- -- -- -- -- [{font: []}] [{align: []}], / / alignment [{align: -- -- -- -- -- []}] [' clean '], / / clear text format -- -- -- -- -- [' clean '] [' image ', 'video'] / / links, images and video -- -- -- -- -- [' link 'and' image ', 'video'] export default {name: 'UE', token: '', components: {quillEditor}, props: ['fMessage'], // to receive parent component data: Function () {return {num: 0, quillUpdateImg: false, content: ' ', // {// Toolbar: {container: ToolbarOptions, // Toolbar handlers: {'image': function (value) { if (value) { document.querySelector('.editor_wrap .avatar-uploader input').click() } else { This.quill. Format ('image', false)}}}}}, // theme: 'snow', placeholder: 'input'}, qiniuForm: {'key': New Date().getTime() + "" + Math.Floor (Math.random() * 1000), new Date().getTime() +" "+ Math.Floor (Math.random() * 1000), SessionStorage. Token, // Backend generated token 'domain': 'http://qvti2smmh.hn-bkt.clouddn.com' // Your domain name}}}, methods: BeforeEditorUpload (res, file) {// Show the upload animation this. quillUpdateIMG = true}, // UploadEditorSuccess (res, Let imgUrl = this.qiniform.domain + '/' + res.key // Reset the key of the uploaded file to prepare for the next upload. }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} = this.$refs.quilleditor. quill // Get the cursor position let length = quill.getSelection().index // Insert image res.info for the image address returned by the server quill.insertEmbed(length, 'image', ImgUrl) // Adjust cursor to last quill-setSelection (length + 1) // Unanimate uploading this. quillUpdateIMG = false}, UploadEditorError (res, file) {// Notification. Error ({// message: 'Upload image failed' //}) console.log(' Failed! This.quillUpdateimg = false}, onEditorChange ({editor, HTML, this.quillUpdateimg = false}, onEditorChange ({editor, HTML, Text}) {this.content = HTML this.$emit(' contentMsg ', HTML) // Pass the contents of the child to the parent}, onEditorFocus () {}, onEditorReady () { }, onEditorBlur () { } }, computed: { editor () { return this.$refs.QuillEditor.quill } }, mounted: Function () {setTimeout(() => {this.content = this.fmessage}, 1100) // Assign the parent to the child. SetTimeout = this.content = this.fMessage}} </script>

(3) style

.quill-editor { height: 300px; } .editor { line-height: normal ! important; height: 500px; }.ql-snow. ql-tooltip[data-mode="link"]::before {content: "Please enter the link address :"; } .ql-snow .ql-tooltip.ql-editing a.ql-action::after { border-right: 0px; Content: "Save "; padding-right: 0px; }.ql-snow. ql-tooltip[data-mode="video"]::before {content: "Please enter video address :"; } .ql-snow .ql-picker.ql-size .ql-picker-label::before, .ql-snow .ql-picker.ql-size .ql-picker-item::before { content: "14px"; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before { content: "10px"; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before { content: "18px"; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before { content: "32px"; } .ql-snow .ql-picker.ql-header .ql-picker-label::before, .ql-snow. Ql-picker.ql-header.ql-picker-item ::before {content: "text "; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, .ql-snow. Ql-picker.ql-header.ql-picker-item [data-value="1"]::before {content: "header 1"; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before, .ql-snow. Ql-picker.ql-header.ql-picker-item [data-value="2"]::before {content: "header 2"; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before, .ql-snow. Ql-picker.ql-header.ql-picker-item [data-value="3"]::before {content: "header 3"; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before, .ql-snow. Ql-picker.ql-header.ql-picker-item [data-value="4"]::before {content: "header 4"; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before, .ql-snow. Ql-picker.ql-header.ql-picker-item [data-value="5"]::before {content: "header 5"; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before, .ql-snow. Ql-picker.ql-header.ql-picker-item [data-value="6"]::before {content: "header 6"; } .ql-snow .ql-picker.ql-font .ql-picker-label::before, .ql-snow .ql-picker.ql-font .ql-picker-item::before { content: "Standard Font "; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before, .ql-snow. Ql-picker.ql-font. Ql-picker-item [data-value="serif"]::before {content: "Serif "; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before, .ql-snow. ql-picker.ql-font-size. Ql-picker-item [data-value=" Monospace "]::before {content: "MonoSpace "; }

Reference in the parent component

(1) temple

// FMessage and ContentMsg are used to put the original content into a function for similar modifications. <squill-editor-qiniu :fMessage="ccontent" v-model="content" @ContentMsg ='getContent'></squill-editor-qiniu> from the parent component

(2) the script

// Declare child components: } getContent (contentMsg) {this.content = contentMsg}}

3, node gets token

router.get('/token', (req, res, Next) = > {const accessKey = 'ZfDWvo39oY - r6Exgz6NZTNlhbTJSuErVlUDuQaPe / / here to fill out seven NiuYun accessKey const secretKey = 'RLUv6WzrZkxc_7PtAIhfXoqn7dxAroNEqvCo2BCH / / here to fill out seven NiuYun secretKey var MAC = new qiniu. The auth. MAC (the accessKey, digest. SecretKey) var options = {scope: 'blogostest', // Fill in the field name expires: } var putPolicy = new Qiniu.rs.putPolicy (options); var uploadToken = putPolicy.uploadToken(mac); let _res = res; {code: 200, MSG: UploadToken} setTimeout(() => {// Return the result to the front page resJSON (_res, _data)}, 500); })