当前位置:网站首页>The quill editor image zooms, multiple rich text boxes are used on one page, and the quill editor upload image address is the server address
The quill editor image zooms, multiple rich text boxes are used on one page, and the quill editor upload image address is the server address
2022-04-23 12:53:00 【ZMJ_ QQ】
quill Official documents Quickstart - Quill Rich Text Editor
Chinese version document Preface · Quill Official Chinese documents · Look at the clouds
Originally used directly quill-editor Rich text , But uploading pictures base64 The encoding length is too long , It needs to be converted into a server url Address , And a page needs to use multiple rich text boxes
Post two reference documents
stay vue3.0 in , Use quill-editor Picture drag and zoom function - Ice morning dew - Blog Garden
Complete code
1、 Installation dependency
npm install vue-quill-editor
npm install quill
npm install quill-image-drop-module
npm install quill-image-resize-module
2、 stay main.js Introduction in
// Rich text
// introduce quill-editor Editor
import VueQuillEditor from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
Vue.use(VueQuillEditor);
// Realization quill-editor Drag and drop the editor to upload pictures
import * as Quill from 'quill'
import { ImageDrop } from 'quill-image-drop-module'
Quill.register('modules/imageDrop', ImageDrop)
// Realization quill-editor The editor resizes the picture
import ImageResize from 'quill-image-resize-module'
Quill.register('modules/imageResize', ImageResize)
3、 Package components editor.vue
If an error is reported when using multiple rich text boxes to upload pictures on a page TypeError: Cannot read property ‘index‘ of null, It's because quill-editor Of ref The value is written dead
Core code
1、 Of rich text components ref value
2、 The method to trigger the image upload must obtain the image corresponding to the rich text in the current page input, Just because the code is wrong , Each uploaded image is inserted into the first rich text box , It took four hours to find out that the method to trigger the upload was not written correctly ┭┮﹏┭┮
3、 Get rich text objects dynamically
4、 Empty after the picture is uploaded successfully input Value , Can solve input Can't upload duplicate files
Complete code
<template>
<div>
<input
type="file"
name="img"
accept="image/jpeg,image/jpg,image/png"
id="quillInput"
class="quill-img"
multiple="multiple"
hidden
@change="getImgUrl($event)"
/>
<quill-editor
class="editor"
:ref="toref"
v-model="content"
:options="editorOption"
@change="onEditorChange(toref)"
@blur="onEditorBlur($event, toref)"
@focus="onEditorFocus($event, toref)"
>
</quill-editor>
</div>
</template>
<script>
import { singleFile, multipleFiles } from "@/api/file";
import { mapGetters } from "vuex";
export default {
name: 'Editor',
props: {
/* The content of the editor */
value: {
type: String
},
/* input Input box Indexes */
quillIndex: {
type: Number,
default: 0
},
/* quill-editor Of ref value */
toref: {
type: String,
default: "quillEditor"
},
toplaceholder: {
type: String,
default: " Please enter ..."
}
},
data() {
return {
content: this.value,
editorOption: {
modules: {
imageDrop: true,
imageResize: {
displayStyles: {
backgroundColor: "black",
border: "none",
color: "white"
},
// modules: ["Resize", "DisplaySize", "Toolbar"]
},
toolbar: {
container: [
["bold", "italic", "underline", "strike"], // In bold Italics Underline Delete line
["blockquote", "code-block"], // quote Code block
[{ header: 1 }, { header: 2 }], // 1、2 Level title
[{ list: "ordered" }, { list: "bullet" }], // Orderly 、 Unordered list
[{ script: "sub" }, { script: "super" }], // Superscript / Subscript
[{ indent: "-1" }, { indent: "+1" }], // Indent
// [{'direction': 'rtl'}], // The text direction
[{ size: ["small", false, "large", "huge"] }], // font size
[{ header: [1, 2, 3, 4, 5, 6, false] }], // title
[{ color: [] }, { background: [] }], // The font color 、 Font background color
[{ font: [] }], // Font type
[{ align: [] }], // Alignment mode
["clean"], // Clear text formatting
["image"], // link 、 picture 、 video
],// Tools menu bar configuration
handlers: {
'image': (value) => {
if (value) {
// upload Click to upload the event
let index = this.quillIndex;
document.querySelectorAll(".quill-img")[index].click();
//document.queryselector("#quillInput").click();
}
}
},
}
},
placeholder: this.toplaceholder, // Tips
readyOnly: false, // Is it read-only
theme: "snow", // The theme snow/bubble
syntax: true, // Syntax checking
},
}
},
computed: {
...mapGetters([
"HOST"
]),
},
watch: {
value() {
this.content = this.value;
},
},
methods: {
// Focus on events Deleting
onEditorFocus(e, ref) {
console.log("foucus", e, ref)
},
// Defocus event Deleting
onEditorBlur(e, ref) {
console.log("blur", ref)
},
onEditorChange(toref) {
// Trigger parent Change the value of the parent component
this.$emit("input", this.content, toref);
},
// Upload pictures in the overview of failure mechanism
getImgUrl(e) {
e.stopPropagation();
if (e.target.files.length > 0) {
this.getMultipleUrl(e.target.files); // Multiple file upload
}
},
getMultipleUrl(file) {
// Multiple file upload
var formData = new FormData();
file.forEach(element => {
formData.append("file", element);
});
multipleFiles(formData).then((res) => {
let quill = this.$refs[this.toref].quill;// Solve the above refs Report errors
if (res.data.code == 20000) {
let list = res.data.data;
list.forEach(element => {
let url = this.HOST + element.afterName; // Splice picture address
// Get the cursor position
let length = quill.selection.savedRange.index;
// Insert a picture res.url The image address returned for the server
quill.insertEmbed(length, "image", url);
// Adjust the cursor to the end
quill.setSelection(length + 1);
});
} else {
this.$message.error(" Picture upload failed !")
}
}).finally(() => {
// Clear the of the input box value, solve input Can't upload duplicate files
let index = this.quillIndex;
document.querySelectorAll(".quill-img")[index].value = null;
});
},
}
}
</script>
<style lang="scss" scoped>
/* Rich text editor Modify height */
.editor {
line-height: normal !important;
margin-bottom: 0;
}
.editor ::v-deep .ql-container {
min-height: 200px !important;
}
</style>
<style>
/* Revised to Chinese */
.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: " preservation ";
padding-right: 0px;
}
.ql-snow .ql-tooltip[data-mode="video"]::before {
content: " Please enter the 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: " title 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: " title 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: " title 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: " title 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: " title 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: " title 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 font ";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
content: " Equal width font ";
}
</style>
4、 Introduce... In the parent component
1、toref The value of should be unique and not repeated ,quillIndex The value of should be the same as that of the rich text component class Same order
2、 Update the value of the parent component
changeEditor(data, model) { // Subcomponents toref Value and v-model The bound values are the same this.qualityList[model] = data; }
Use multiple rich text boxes in the parent component
<editor
v-if="edit"
toref="qualityAppraisalPlan"
:quillIndex="0"
v-model="qualityList.qualityAppraisalPlan"
@input="changeEditor"
/>
<div
v-if="!edit"
class="ql-editor"
v-html="qualityList.qualityAppraisalPlan"
></div>
<p> One 、 Appraisal object </p>
<editor
v-if="edit"
toref="identificationObject"
:quillIndex="1"
v-model="qualityList.identificationObject"
toplaceholder=" Please enter the identification object ..."
@input="changeEditor"
/>
<div
style="padding-left: 20px"
v-if="!edit"
class="ql-editor"
v-html="qualityList.identificationObject"
></div>
Screenshot of the page
版权声明
本文为[ZMJ_ QQ]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230616457199.html
边栏推荐
猜你喜欢
[unity note] basic lighting in l4unity
[vulnhub range] - DC2
CVPR 2022&NTIRE 2022|首个用于高光谱图像重建的 Transformer
Idea的src子文件下无法创建servlet
NPDP | how can product managers not be excluded by programmers?
22. 括号生成
STM32工程移植:不同型号芯片工程之间的移植:ZE到C8
[csnote] ER diagram
Object.keys后key值数组乱序的问题
Unlock openharmony technology day! The annual event is about to open!
随机推荐
甲辰篇 創世紀《「內元宇宙」聯載》
flask项目跨域拦截处理以及dbm数据库学习【包头文创网站开发】
BUUCTF WEB [BUUCTF 2018]Online Tool
8 websites that should be known for product development to enhance work experience
31. Next arrangement
SSM framework series - JUnit unit test optimization day2-3
SSM框架系列——注解开发day2-2
BUUCTF WEB [BJDCTF2020]ZJCTF,不过如此
mysql中 innoDB执行过程分析
Use source insight to view and edit source code
Stm32cubeprogrammer basic instructions
实现一个盒子在父盒子中水平垂直居中的几种“姿势”
Uni app native app cloud packaging integrated Aurora push (jg-jpush) detailed tutorial
Zigbee之CC2530最小系统及寄存器配置(1)
【csnote】ER图
大家帮我看一下这是啥情况,MySQL5.5的。谢了
uni-app 原生APP-本地打包集成极光推送(JG-JPUSH)详细教程
XinChaCha Trust SSL Organization Validated
Unable to create servlet under SRC subfile of idea
Kubernetes 入门教程