此篇笔记记录的是vue-quill-edter的进阶版,如果还没有安装过quill需要查看 https://www.cnblogs.com/meiyanstar/p/12909755.html(vue-quill-editer安装初级版)
实现功能:
- 设置工具栏展示的工具选项
- 工具栏功能提示
- 事件重写,实现文件上传功能
- 事件重写,实现图片上传功能
- 实现图片拖拽上传
- 实现上传到富文本里的图片进行拖拽改变图片大小
一、富文本组件页面全部代码(QuillEditer.vue)
<template> <div class="edit_container"> <quill-editor class="ql-editor" v-model="content" :id="id" :ref="refs" :options="quillOption" @focus="onEditorFocus($event)" @blur="onEditorBlur($event)" @change="onEditorChange($event)" ></quill-editor> </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\' import quillConfig from \'@/utils/quillconfig.js\' import \'quill/dist/quill.min.js\' // 上传文件 插入a链接 import { Quill } from \'vue-quill-editor\' // 自定义插入a链接 var Link = Quill.import(\'formats/link\') class FileBlot extends Link { // 继承Link Blot static create(value) { let node = undefined if (value && !value.href) { // 适应原本的Link Blot node = super.create(value) } else { // 自定义Link Blot node = super.create(value.href) // node.setAttribute(\'download\', value.innerText); // 左键点击即下载 node.innerText = value.innerText node.download = value.innerText } return node } } FileBlot.blotName = \'link\' FileBlot.tagName = \'A\' Quill.register(FileBlot) // 上传文件 插入a链接over export default { name: \'VueQuillEditor\', components: { quillEditor }, props: [\'id\', \'refs\', \'quillContent\'], data () { return { content: null, // 富文本内容 quillOption: quillConfig,//各配置项 } }, created () { this.content = this.quillContent }, mounted() { autotip:{ document.getElementsByClassName(\'ql-editor\')[0].dataset.placeholder=\'\' for(let item of quillConfig.titleConfig){ let tip = document.querySelector(\'.quill-editor \'+ item.Choice) if (!tip) continue tip.setAttribute(\'title\',item.title) } } }, methods: { // 失去焦点事件 onEditorBlur (quill) { // console.log(\'editor blur!\', quill) }, // 获得焦点事件 onEditorFocus (quill) { // console.log(\'editor focus!\', quill) }, // 准备富文本编辑器 onEditorReady (quill) { // console.log(\'editor ready!\', quill) }, // 富文本内容改变事件 onEditorChange ({ quill, html, text }) { this.content = html this.$emit(\'childQuill\',html) }, } } </script> <style scoped > .ql-editor { line-height: normal !important; /* width: 335px; 我是需要展示给手机端所以设置了宽 */ } .ql-snow .ql-tooltip[data-mode=\'link\']::before { content: \'请输入链接地址:\'; } .ql-snow .ql-tooltip.ql-editing a.ql-action::after { border-right: 0px; content: \'保存\'; padding-right: 0px; } .ql-snow .ql-tooltip[data-mode=\'video\']::before { content: \'请输入视频地址:\'; } .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: \'文本\'; } .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: \'标题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: \'标题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: \'标题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: \'标题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: \'标题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: \'标题6\'; } .ql-snow .ql-picker.ql-font .ql-picker-label::before, .ql-snow .ql-picker.ql-font .ql-picker-item::before { content: \'标准字体\'; } .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: \'衬线字体\'; } .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: \'等宽字体\'; } </style> <style> /* 自定义上传文件的icon */ .ql-upload{ background-image: url("../assets/images/file.svg") !important; background-size: 16px 16px !important; background-position: center center !important; background-repeat:no-repeat !important; } /* 隐藏文件上传的input type=file的样式 */ input.ql-upload { height: 0 !important; width: 0 !important; padding: 0 !important; } </style>
二、富文本配置的全部代码(quillconfig.js)
import { quillUploadimgAndfile } from "@/api/wenjuan"; //上传图片和文件的接口 //quill图片可拖拽上传 import { ImageDrop } from \'quill-image-drop-module\'; Quill.register(\'modules/imageDrop\', ImageDrop); //quill图片可拖拽改变大小 import ImageResize from \'quill-image-resize-module\' Quill.register(\'modules/imageResize\', ImageResize) // toolbar工具栏的工具选项(默认展示全部) const toolOptions = [ [\'bold\', \'italic\', \'underline\', \'strike\'], [\'blockquote\', \'code-block\'], [{\'header\': 1}, {\'header\': 2}], [{\'list\': \'ordered\'}, {\'list\': \'bullet\'}], [{\'script\': \'sub\'}, {\'script\': \'super\'}], [{\'indent\': \'-1\'}, {\'indent\': \'+1\'}], [{\'direction\': \'rtl\'}], [{\'size\': [\'small\', false, \'large\', \'huge\']}], [{\'header\': [1, 2, 3, 4, 5, 6, false]}], [{\'color\': []}, {\'background\': []}], [{\'font\': []}], [{\'align\': []}], [\'clean\'], [\'link\', \'image\'], [\'upload\'], ]; const handlers = { // 实现图片上传功能 image: function image() { var self = this; var fileInput = this.container.querySelector(\'input.ql-image[type=file]\'); if (fileInput === null) { fileInput = document.createElement(\'input\'); fileInput.setAttribute(\'type\', \'file\'); // 设置图片参数名 fileInput.setAttribute(\'name\', \'file\'); // 可设置上传图片的格式 fileInput.setAttribute(\'accept\',\'image/png, image/gif, image/jpeg, image/bmp, image/x-icon\'); fileInput.classList.add(\'ql-image\'); // 监听选择文件 fileInput.addEventListener(\'change\', function () { let formData = new FormData() formData.append(\'file\',fileInput.files[0]) quillUploadimgAndfile(formData).then(data => {//quillUploadimgAndfile是封装好的上传文件的方法 if (data.data.code === 1) { let length = self.quill.getSelection(true).index; self.quill.insertEmbed(length, \'image\', data.data.data.url); self.quill.insertEmbed(length, \'title\', data.data.data.fileName); self.quill.setSelection(length + 1) }else { this.$message.error(data.data.info) } }).catch(err => { }) }); this.container.appendChild(fileInput); } fileInput.click(); }, // 实现文件上传功能 upload:function upload() { var self = this; var fileInput = self.container.querySelector(\'input.ql-upload[type=file]\'); if (fileInput === null) { fileInput = document.createElement(\'input\'); fileInput.setAttribute(\'type\', \'file\'); // 设置图片参数名 fileInput.setAttribute(\'name\', \'file\'); // 限制上传文件的格式 具体限制格式类型见文章底部 // fileInput.setAttribute(\'accept\',\'image/png, image/gif, image/jpeg, image/bmp, image/x-icon\'); fileInput.classList.add(\'ql-upload\'); // 监听选择文件 console.log(\'self.quill\',self.quill) fileInput.addEventListener(\'change\', function () { let formData = new FormData() formData.append(\'file\',fileInput.files[0]) quillUploadimgAndfile(formData).then(data => {//quillUploadimgAndfile是封装好的上传文件的方法 if (data.data.code === 1) { console.log(\'asdasda\',data.data.data) let length = self.quill.getSelection(true).index; // 插入文件,data为服务器返回的文件链接地址 //**注意这里 - 插入文件地址的方式** self.quill.insertEmbed(length, \'link\', {href: data.data.data.url, innerText: data.data.data.fileName}) self.quill.setSelection(length + 1) }else { self.$message.error(data.data.info) } }).catch(err => { }) }); this.container.appendChild(fileInput); } fileInput.click(); } }; // 工具栏功能提示 const titleConfig=[ {Choice:\'.ql-bold\',title:\'加粗\'}, {Choice:\'.ql-italic\',title:\'斜体\'}, {Choice:\'.ql-underline\',title:\'下划线\'}, {Choice:\'.ql-header\',title:\'段落格式\'}, {Choice:\'.ql-strike\',title:\'删除线\'}, {Choice:\'.ql-blockquote\',title:\'块引用\'}, {Choice:\'.ql-code\',title:\'插入代码\'}, {Choice:\'.ql-code-block\',title:\'插入代码段\'}, {Choice:\'.ql-font\',title:\'字体\'}, {Choice:\'.ql-size\',title:\'字体大小\'}, {Choice:\'.ql-list[value="ordered"]\',title:\'编号列表\'}, {Choice:\'.ql-list[value="bullet"]\',title:\'项目列表\'}, {Choice:\'.ql-direction\',title:\'文本方向\'}, {Choice:\'.ql-header[value="1"]\',title:\'h1\'}, {Choice:\'.ql-header[value="2"]\',title:\'h2\'}, {Choice:\'.ql-align\',title:\'对齐方式\'}, {Choice:\'.ql-color\',title:\'字体颜色\'}, {Choice:\'.ql-background\',title:\'背景颜色\'}, {Choice:\'.ql-image\',title:\'图像\'}, {Choice:\'.ql-upload\',title:\'文件\'}, {Choice:\'.ql-link\',title:\'添加链接\'}, {Choice:\'.ql-formula\',title:\'插入公式\'}, {Choice:\'.ql-clean\',title:\'清除字体格式\'}, {Choice:\'.ql-script[value="sub"]\',title:\'下标\'}, {Choice:\'.ql-script[value="super"]\',title:\'上标\'}, {Choice:\'.ql-indent[value="-1"]\',title:\'向左缩进\'}, {Choice:\'.ql-indent[value="+1"]\',title:\'向右缩进\'}, {Choice:\'.ql-header .ql-picker-label\',title:\'标题大小\'}, {Choice:\'.ql-header .ql-picker-item[data-value="1"]\',title:\'标题一\'}, {Choice:\'.ql-header .ql-picker-item[data-value="2"]\',title:\'标题二\'}, {Choice:\'.ql-header .ql-picker-item[data-value="3"]\',title:\'标题三\'}, {Choice:\'.ql-header .ql-picker-item[data-value="4"]\',title:\'标题四\'}, {Choice:\'.ql-header .ql-picker-item[data-value="5"]\',title:\'标题五\'}, {Choice:\'.ql-header .ql-picker-item[data-value="6"]\',title:\'标题六\'}, {Choice:\'.ql-header .ql-picker-item:last-child\',title:\'标准\'}, {Choice:\'.ql-size .ql-picker-item[data-value="small"]\',title:\'小号\'}, {Choice:\'.ql-size .ql-picker-item[data-value="large"]\',title:\'大号\'}, {Choice:\'.ql-size .ql-picker-item[data-value="huge"]\',title:\'超大号\'}, {Choice:\'.ql-size .ql-picker-item:nth-child(2)\',title:\'标准\'}, {Choice:\'.ql-align .ql-picker-item:first-child\',title:\'居左对齐\'}, {Choice:\'.ql-align .ql-picker-item[data-value="center"]\',title:\'居中对齐\'}, {Choice:\'.ql-align .ql-picker-item[data-value="right"]\',title:\'居右对齐\'}, {Choice:\'.ql-align .ql-picker-item[data-value="justify"]\',title:\'两端对齐\'} ]; export default { placeholder: \'\', theme: \'snow\', // 主题 modules: { toolbar: { container: toolOptions, // 工具栏选项 handlers: handlers, // 事件重写 }, imageResize: {},// 拖拽改变图片大小 imageDrop:true, // 拖拽上传文件 }, titleConfig, };
补充:上传文件限制类型:https://www.cnblogs.com/meiyanstar/p/14676408.html