浅谈vue中使用编辑器vue-quill-editor踩过的坑


Posted in Javascript onAugust 03, 2020

结合vue+element-ui+vue-quill+editor二次封装成组件

1.图片上传

分析原因

项目中使用vue-quill-editor富文本编辑器,在编辑内容的时候,我们往往会编辑图片,而vue-quill-editor默认的处理方式是直接将图片转成base64格式,导致上传的内容十分庞大,且服务器接受post的数据的大小是有限制的,很有可能就提交失败,造成用户体验差。

引入element-ui

编辑editor.vue文件

<template>
  <div>
    <!-- 图片上传组件辅助-->
    <el-upload
      class="avatar-uploader"
      action=""
      accept="image/jpg, image/jpeg, image/png, image/gif"
      :http-request="upload"
      :before-upload="beforeUploadImg"
      :on-success="uploadSuccess"
      :on-error="uploadError"
      :show-file-list="false">
      <i class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
  </div>
</template>
<script>
  import axios from '@/API/';
	import { quillEditor } from "vue-quill-editor";
	import COS from "cos-js-sdk-v5";
	import Upload from '@/components/Upload.vue';
	import { addQuillTitle } from '../utils/quill-title.js';

	import "quill/dist/quill.core.css";
	import "quill/dist/quill.snow.css";
	import "quill/dist/quill.bubble.css";
	
  export default {
    data() {
      return {
      }
    },
    methods: {
      // 上传图片前
      beforeUpload(res, file) {
      	const isJPG = file.type === 'image/jpg' || file.type === 'image/png' || file.type === 'image/jpeg' 
		    const isLt1M = file.size / 1024 / 1024 < 1
		    if (!isJPG) {
		      this.$message.error('支持JPG、PNG格式的图片,大小不得超过1M')
		    }
		    if (!isLt1M) {
		      this.$message.error('文件最大不得超过1M')
		    } 
		    return isJPG && isLt1M
      },
      // 上传图片成功
      uploadSuccess(res, file) {},
      // 上传图片失败
      uploadError(res, file) {},
      // 上传图片处理过程
      upload(req){}
    }
  }
</script>

在editor.vue中引入vue-quill-editor

<template>
  <div>
    <!-- 图片上传组件辅助-->
    <el-upload
      class="avatar-uploader"
      action=""
      accept="image/jpg, image/jpeg, image/png, image/gif"
      :http-request="upload"
      :before-upload="beforeUploadImg"
      :on-success="uploadSuccess"
      :on-error="uploadError"
      :show-file-list="false">
      <i class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
    <quill-editor 
      class="info-editor" 
      v-model="content" 
      ref="QuillEditor" 
      :options="editorOption" 
      @blur="onEditorBlur($event)"
      @focus="onEditorFocus($event)"
      @ready="onEditorReady($event)">
    </quill-editor>
  </div>
</template>
<script>
  import axios from '@/API/';
	import { quillEditor } from "vue-quill-editor";
	import COS from "cos-js-sdk-v5";
	import Upload from '@/components/Upload.vue';
	import { addQuillTitle } from '../utils/quill-title.js';

	import "quill/dist/quill.core.css";
	import "quill/dist/quill.snow.css";
	import "quill/dist/quill.bubble.css";

  // 工具栏配置
  const toolbarOptions = [
	 ['bold', 'italic', 'underline', 'strike'],    // toggled buttons
	 ['blockquote', 'code-block'],

	 [{'header': 1}, {'header': 2}],        // custom button values
	 [{'list': 'ordered'}, {'list': 'bullet'}],
	 [{'script': 'sub'}, {'script': 'super'}],   // superscript/subscript
	 [{'indent': '-1'}, {'indent': '+1'}],     // outdent/indent
	 [{'direction': 'rtl'}],             // text direction

	 [{'size': ['small', false, 'large', 'huge']}], // custom dropdown
	 [{'header': [1, 2, 3, 4, 5, 6, false]}],

	 [{'color': []}, {'background': []}],     // dropdown with defaults from theme
	 [{'font': []}],
	 [{'align': []}],
	 ['link', 'image', 'video'],
	 ['clean']                     // remove formatting button
	]

  export default {
    data() {
      return {
      	editorOption: {
      		placeholder: '请输入编辑内容',
      		theme: 'snow', //主题风格
      		modules: {
      			toolbar: {
      				container: toolbarOptions, // 工具栏
      				handlers: {
      					'image': function (value) {
      						if (value) {
      							document.querySelector('#quill-upload input').click()
      						} else {
      							this.quill.format('image', false);
      						}
      					}
      				}
      			}
      		}
      	}, // 富文本编辑器配置
      	content: '', //富文本内容
      }
    },
    methods: {
      // 上传图片前
      beforeUpload(res, file) {
      	const isJPG = file.type === 'image/jpg' || file.type === 'image/png' || file.type === 'image/jpeg' 
		    const isLt1M = file.size / 1024 / 1024 < 1
		    if (!isJPG) {
		      this.$message.error('支持JPG、PNG格式的图片,大小不得超过1M')
		    }
		    if (!isLt1M) {
		      this.$message.error('文件最大不得超过1M')
		    } 
		    return isJPG && isLt1M
      },
      // 上传图片成功
      uploadSuccess(res, file) {
      	let quill = this.$refs.QuillEditor.quill;
	      let length = quill.getSelection().index;
	      quill.insertEmbed(length, 'image', url);
	      quill.setSelection(length+1)
      },
      // 上传图片失败
      uploadError(res, file) {
        this.$message.error('图片插入失败')
      },
      // 上传图片处理过程
      upload(req){}
    }
  }
</script>

<style scoped>
.avatar-uploader{
	display: none;
}
</style>

2.编辑器上增加title提示

在编辑器上增加一个quill-title.js的工具栏的title的配置文件

const titleConfig = {
 'ql-bold':'加粗',
 'ql-color':'字体颜色',
 'ql-font':'字体',
 'ql-code':'插入代码',
 'ql-italic':'斜体',
 'ql-link':'添加链接',
 'ql-background':'背景颜色',
 'ql-size':'字体大小',
 'ql-strike':'删除线',
 'ql-script':'上标/下标',
 'ql-underline':'下划线',
 'ql-blockquote':'引用',
 'ql-header':'标题',
 'ql-indent':'缩进',
 'ql-list':'列表',
 'ql-align':'文本对齐',
 'ql-direction':'文本方向',
 'ql-code-block':'代码块',
 'ql-formula':'公式',
 'ql-image':'图片',
 'ql-video':'视频',
 'ql-clean':'清除字体样式'
};



export function addQuillTitle(){
 const oToolBar = document.querySelector('.ql-toolbar'),
    aButton = oToolBar.querySelectorAll('button'),
    aSelect = oToolBar.querySelectorAll('select'),
    aSpan= oToolBar.querySelectorAll('span');
 aButton.forEach((item)=>{
  if(item.className === 'ql-script'){
   item.value === 'sub' ? item.title = '下标': item.title = '上标';
  }else if(item.className === 'ql-indent'){
   item.value === '+1' ? item.title ='向右缩进': item.title ='向左缩进';
  }else if(item.className === 'ql-list'){
   item.value==='ordered' ? item.title='有序列表' : item.title='无序列表'
  }else if(item.className === 'ql-header'){
   item.value === '1' ? item.title = '标题H1': item.title = '标题H2';
  }else{
   item.title = titleConfig[item.classList[0]];
  }
 });
 aSelect.forEach((item)=>{
  if(item.className!='ql-color'&&item.className!='ql-background'){
   item.parentNode.title = titleConfig[item.classList[0]];
  }
 });
 aSpan.forEach((item)=>{
  if(item.classList[0]==='ql-color'){
   item.title = titleConfig[item.classList[0]];
  }else if(item.classList[0]==='ql-background'){
   item.title = titleConfig[item.classList[0]];
  }
 });
}

在editor.vue中引入quill-title.js

<template>
  <div>
    <!-- 图片上传组件辅助-->
    <el-upload
      class="avatar-uploader"
      action=""
      accept="image/jpg, image/jpeg, image/png, image/gif"
      :http-request="upload"
      :before-upload="beforeUploadImg"
      :on-success="uploadSuccess"
      :on-error="uploadError"
      :show-file-list="false">
      <i class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
    <quill-editor 
      class="info-editor" 
      v-model="content" 
      ref="QuillEditor" 
      :options="editorOption" 
      @blur="onEditorBlur($event)"
      @focus="onEditorFocus($event)"
      @ready="onEditorReady($event)">
    </quill-editor>
  </div>
</template>
<script>
  import axios from '@/API/';
	import { quillEditor } from "vue-quill-editor";
	import COS from "cos-js-sdk-v5";
	import Upload from '@/components/Upload.vue';
	import { addQuillTitle } from '../utils/quill-title.js';

	import "quill/dist/quill.core.css";
	import "quill/dist/quill.snow.css";
	import "quill/dist/quill.bubble.css";

  // 工具栏配置
  const toolbarOptions = [
	 ['bold', 'italic', 'underline', 'strike'],    // toggled buttons
	 ['blockquote', 'code-block'],

	 [{'header': 1}, {'header': 2}],        // custom button values
	 [{'list': 'ordered'}, {'list': 'bullet'}],
	 [{'script': 'sub'}, {'script': 'super'}],   // superscript/subscript
	 [{'indent': '-1'}, {'indent': '+1'}],     // outdent/indent
	 [{'direction': 'rtl'}],             // text direction

	 [{'size': ['small', false, 'large', 'huge']}], // custom dropdown
	 [{'header': [1, 2, 3, 4, 5, 6, false]}],

	 [{'color': []}, {'background': []}],     // dropdown with defaults from theme
	 [{'font': []}],
	 [{'align': []}],
	 ['link', 'image', 'video'],
	 ['clean']                     // remove formatting button
	]

  export default {
    data() {
      return {
      	editorOption: {
      		placeholder: '请输入编辑内容',
      		theme: 'snow', //主题风格
      		modules: {
      			toolbar: {
      				container: toolbarOptions, // 工具栏
      				handlers: {
      					'image': function (value) {
      						if (value) {
      							document.querySelector('#quill-upload input').click()
      						} else {
      							this.quill.format('image', false);
      						}
      					}
      				}
      			}
      		}
      	}, // 富文本编辑器配置
      	content: '', //富文本内容
      }
    },
    mounted(){
	    addQuillTitle();
	  },
    methods: {
      // 上传图片前
      beforeUpload(res, file) {
      	const isJPG = file.type === 'image/jpg' || file.type === 'image/png' || file.type === 'image/jpeg' 
		    const isLt1M = file.size / 1024 / 1024 < 1
		    if (!isJPG) {
		      this.$message.error('支持JPG、PNG格式的图片,大小不得超过1M')
		    }
		    if (!isLt1M) {
		      this.$message.error('文件最大不得超过1M')
		    } 
		    return isJPG && isLt1M
      },
      // 上传图片成功
      uploadSuccess(res, file) {
      	let quill = this.$refs.QuillEditor.quill;
	      let length = quill.getSelection().index;
	      quill.insertEmbed(length, 'image', url);
	      quill.setSelection(length+1)
      },
      // 上传图片失败
      uploadError(res, file) {
        this.$message.error('图片插入失败')
      },
      // 上传图片处理过程
      upload(req){}
    }
  }
</script>

<style scoped>
.avatar-uploader{
	display: none;
}
</style>

补充知识:Vue引用quill富文本编辑器,图片处理的两个神器插件(quill-image-drop-module、quill-image-resize-module)的正确姿势。(解决各种报错)

一、前言

我在vue-quill-editor的Github认识了这两个插件。

quill-image-drop-module:允许粘贴图像并将其拖放到编辑器中。

quill-image-resize-module:允许调整图像大小。

都很实用呐!

然而DEMO不够详细,实际引用时,报了很多错误。

Cannot read property 'imports' of undefined"、

Failed to mount component: template or render function not defined.、

Cannot read property 'register' of undefined。

下面说一下正确的引用姿势。

二、我的环境

Webpack + Vue-Cli 2.0 (vue init非simple的版本)

三、正文

1、确保你的quill富文本编辑器(不添加插件时)可以正常运行。

2、安装NPM依赖。

cnpm install quill-image-drop-module -S

cnpm install quill-image-resize-module -S

3、在build文件夹下找到webpack.base.conf.js。

修改:

module.exports = {
 plugins: [
     new webpack.ProvidePlugin({
     // 在这儿添加下面两行
       'window.Quill': 'quill/dist/quill.js',
       'Quill': 'quill/dist/quill.js'
    })
 ]
}

4、修改你在页面引用的“quill富文本组件”。

修改<script>标签内代码:

// 以前需要有下面几行:
  import { quillEditor } from 'vue-quill-editor' //注意quillEditor必须加大括号,否则报错。
  import "quill/dist/quill.core.css";//
  import "quill/dist/quill.snow.css";

  // 新增下面代码:
  import resizeImage from 'quill-image-resize-module' // 调整大小组件。
  import { ImageDrop } from 'quill-image-drop-module'; // 拖动加载图片组件。
  Quill.register('modules/imageDrop', ImageDrop);
  Quill.register('modules/resizeImage ', resizeImage )

然后,修改页面引用的:options="editorOption"。

editorOption: {
 modules: {
 // 新增下面
 imageDrop: true, // 拖动加载图片组件。
    imageResize: { //调整大小组件。
       displayStyles: {
         backgroundColor: 'black',
         border: 'none',
         color: 'white'
       },
       modules: [ 'Resize', 'DisplaySize', 'Toolbar' ]
     }
 }
}

重新 npm run dev ,插件运行成功!

以上这篇浅谈vue中使用编辑器vue-quill-editor踩过的坑就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Web前端设计模式  制作漂亮的弹出层
Oct 29 Javascript
js对象关系图 方便dom操作
Mar 18 Javascript
javascript中数组中求最大值示例代码
Dec 18 Javascript
javascript 用函数语句和表达式定义函数的区别详解
Jan 06 Javascript
JS判断移动端访问设备并加载对应CSS样式
Jun 13 Javascript
AngularJS入门教程之学习环境搭建
Dec 06 Javascript
Javascript中获取浏览器类型和操作系统版本等客户端信息常用代码
Jun 28 Javascript
详解Vue 非父子组件通信方法(非Vuex)
May 24 Javascript
vue.js实现条件渲染的实例代码
Jun 22 Javascript
jQuery实现的响应鼠标移动方向插件用法示例【附源码下载】
Aug 28 jQuery
JavaScript 预解析的4种实现方法解析
Sep 03 Javascript
vue在线动态切换主题色方案
Mar 26 Javascript
Vue 实现对quill-editor组件中的工具栏添加title
Aug 03 #Javascript
简单了解three.js 着色器材质
Aug 03 #Javascript
Element InputNumber 计数器的实现示例
Aug 03 #Javascript
解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题
Aug 03 #Javascript
Vue 根据条件判断van-tab的显示方式
Aug 03 #Javascript
在vue中使用el-tab-pane v-show/v-if无效的解决
Aug 03 #Javascript
Vue解决echart在element的tab切换时显示不正确问题
Aug 03 #Javascript
You might like
PHP 加密与解密的斗争
2009/04/17 PHP
ThinkPHP2.0读取MSSQL提示Incorrect syntax near the keyword 'AS'的解决方法
2014/06/25 PHP
php解析http获取的json字符串变量总是空白null
2015/03/02 PHP
php中session_id()函数详细介绍,会话id生成过程及session id长度
2015/09/23 PHP
PHP Mysqli 常用代码集合
2016/11/12 PHP
jQuery 第二课 操作包装集元素代码
2010/03/14 Javascript
判断javascript的数据类型(示例代码)
2013/12/11 Javascript
jquery ajax传递中文参数乱码问题及解决方法说明
2014/02/07 Javascript
javascript 模拟坦克大战游戏(html5版)附源码下载
2014/04/08 Javascript
模拟一个类似百度google的模糊搜索下拉列表
2014/04/15 Javascript
jQuery中;function($,undefined) 前面的分号的用处
2014/12/17 Javascript
jQuery显示和隐藏 常用的状态判断方法
2015/01/29 Javascript
JavaScript实现将xml转换成html table表格的方法
2015/04/17 Javascript
在其他地方你学不到的jQuery小贴士和技巧(欢迎收藏)
2016/01/20 Javascript
使用jquery.qrcode.min.js实现中文转化二维码
2016/03/11 Javascript
微信小程序 购物车简单实例
2016/10/24 Javascript
JS如何生成一个不重复的ID的函数
2016/12/25 Javascript
jQuery插件HighCharts实现2D柱状图、折线图的组合多轴图效果示例【附demo源码下载】
2017/03/09 Javascript
Bootstrap学习笔记 轮播(Carousel)插件
2017/03/21 Javascript
深入理解node.js之path模块
2017/05/03 Javascript
AngularJS基于provider实现全局变量的读取和赋值方法
2017/06/28 Javascript
原生js实现密码输入框值的显示隐藏
2017/07/17 Javascript
基于jQuery中ajax的相关方法汇总(必看篇)
2017/11/08 jQuery
jQuery实现的手动拖动控制进度条效果示例【测试可用】
2018/04/18 jQuery
纯js封装的ajax功能函数与用法示例
2018/05/14 Javascript
详解Vue组件插槽的使用以及调用组件内的方法
2018/11/13 Javascript
express框架中使用jwt实现验证的方法
2019/08/25 Javascript
聊聊vue 中的v-on参数问题
2021/01/29 Vue.js
[02:16]2018年度CS GO最具人气选手-完美盛典
2018/12/16 DOTA
Python下线程之间的共享和释放示例
2015/05/04 Python
Python使用reportlab模块生成PDF格式的文档
2019/03/11 Python
Python实现的爬取豆瓣电影信息功能案例
2019/09/15 Python
浅谈matplotlib中FigureCanvasXAgg的用法
2020/06/16 Python
定制iPhone和Macbook保护壳:Slick Case
2018/11/21 全球购物
大学生实习推荐信
2015/03/27 职场文书
浅谈tf.train.Saver()与tf.train.import_meta_graph的要点
2021/05/26 Python