vue-quill-editor实现图片上传功能


Posted in Javascript onAugust 08, 2017

问题描述

  项目使用的vue2.0开发,项目中需要一个富文本编辑器,楼主经过一番心理挣扎选择了vue-quill-editor。具体如何引用作者在项目中已经写得很明白了,我在这里就不再赘述。
  vue-quill-editor插入图片的方式是将图片转为base64再放入内容中,这样就会产生一个问题,如果图片比较大的话,富文本的内容就会很大,楼主是将内容存在数据库中的,这样一来,一方面会占用大量的数据库存储空间,另一方面当图片太大的时候富文本的内容,会超过数据库的存储上限,从而会产生内容被截断从而显示不全的问题(即使是text类型,也有存储上限65535)。
  那么问题来了,如何将图片上传到自己的服务器或第三方服务,然后将获得的图片url插入到文本中呢?我认为大致有两个方法,其一是将任务交给服务端,服务端截取base64图片并转化为文件,将其路径或者url替换原来的图片数据;其二是对控件本身下手,首先将图片上传,然后插入到富文本中。接下来楼主就开始了自己的踩坑之路。

解决方案

基础简介

1.vue-quill-editor是基于quill(github地址)适用于Vue2的富文本编辑器,所以对于quill的原生属性扩展也是支持的。quill文档地址

2.quill 中有许多扩展和自定义方法功能。比如图片的重定义大小、图片上传的点击处理等。

图片上传

通过查看quill项目issue。发现其中是有对图片上传这方面问题进行考虑和修改的。所以图片上传这个方案是可行的。接下来就是如何实现。

3.首先我们需要在项目中拿到quill的实例。这个在vue-quill-editor项目中有介绍如何获取。基本方法就是通过ref获取你的vue-quill-editor实例,再获取quill实例,代码如下。其中newEditor就是我的vue-quill-editor

 this.$refs.newEditor.quill

4.在拿到实例后我们需要考虑如何图片上传并将url插入文本中。通过查找发现可以注册一个自定义的图片处理函数,当顶部的工具栏中的图片按钮被点击的时候,就会触发这个函数。然而在实际使用中你会发现这个函数并不像文档中所说的接收(image, callback)两个参数,image是你的图片,你只需要在callback中将传入处理后的url就可以。而是接收一个参数state,当被点击时就会触发这个函数,并传入state值----true。这里首先介绍一下,如何注册这个处理函数-imgHandler。这里要注意,注册函数要写在mounted生命周期钩子里。

mounted() {
var vm =this
 var imgHandler = async function(state) {
 if (state) {
 //button is clicked
 }
 }
 vm.$refs.newEditor.quill.getModule("toolbar").addHandler("image", imgHandler)
}

5.通过在stackflow查阅,发现就只能在imgHandler中自己实现点击上传和插入的功能。这样就在editor下面写一个不显示的input,并监听变化上传图片,获取其实例,当imgHandler被点击时,模拟input按钮被点击。代码变成如下示例。

mounted() {
 var vm =this
 var imgHandler = async function(image) {
 vm.addImgRange = vm.$refs.newEditor.quill.getSelection()
 if (image) {
  var fileInput = document.getElementById(vm.uniqueId) //隐藏的file文本ID
  fileInput.click() //加一个触发事件
 }
 }
 vm.$refs.newEditor.quill.getModule("toolbar").addHandler("image", imgHandler)
 }

6.最后是input的点击上传和图片url的插入。

HTML代码

<div
 v-loading="imageLoading"
 element-loading-text="请稍等,图片上传中">
 <quill-editor
 ref="newEditor"
 :options="newOption"
 style="height: 200px; margin-bottom: 54px"
 v-model="editorContent"
 @change="editorChange">
 </quill-editor>
 <form action="" method="post" enctype="multipart/form-data" id="uploadFormMulti">
 <input style="display: none" :id="uniqueId" type="file" name="avator" multiple accept="image/jpg,image/jpeg,image/png,image/gif" @change="uploadImg('uploadFormMulti')"><!--style="display: none"-->
 </form>
 </div>

vue代码

uploadImg: async function(id) {
  var vm = this
  vm.imageLoading = true
  var formData = new FormData($('#' + id)[0])
  try {
  const url = await vm.uploadImgReq(formData)// 自定义的图片上传函数
  if (url != null && url.length > 0) {
  var value = url
  vm.addImgRange = vm.$refs.newEditor.quill.getSelection()
  value = value.indexOf('http') != -1 ? value : 'http:' + value
  vm.$refs.newEditor.quill.insertEmbed(vm.addImgRange != null?vm.addImgRange.index:0, 'image', value, Quill.sources.USER)
  } else {
  vm.$message.warning("图片增加失败")
  }
  document.getElementById(vm.uniqueId).value=''
  } catch ({message: msg}) {
  document.getElementById(vm.uniqueId).value=''
  vm.$message.warning(msg)
  }
  vm.imageLoading = false
 },

到这里就大功告成啦。如果有什么错误、问题或者更好的解决方案欢迎指正讨论~
最后,在解决这个问题的时候,顺便把ImageResize集成到了控件中。具体实现比较简单可以参考vue-quill-editor中的demo示例

import Quill from 'quill'
 import { ImageResize } from '../modules/ImageResize.js'
 Quill.register('modules/imageResize', ImageResize)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript让IE浏览器event对象符合W3C DOM标准
Nov 24 Javascript
表头固定(利用jquery实现原理介绍)
Nov 08 Javascript
jquery表格内容筛选实现思路及代码
Apr 16 Javascript
仿当当网淘宝网等主流电子商务网站商品分类导航菜单
Sep 25 Javascript
JS实现网页顶部向下滑出的全国城市切换导航效果
Aug 22 Javascript
javascript运动效果实例总结(放大缩小、滑动淡入、滚动)
Jan 08 Javascript
实例剖析AngularJS框架中数据的双向绑定运用
Mar 04 Javascript
Bootstrap组件(一)之菜单
May 11 Javascript
JS实现的Unicode编码转换操作示例
Apr 28 Javascript
vue + element-ui实现简洁的导入导出功能
Dec 22 Javascript
layui 监听表格复选框选中值的方法
Aug 15 Javascript
最简单的JS实现json转csv的方法
Jan 10 Javascript
vue.js评论发布信息可插入QQ表情功能
Aug 08 #Javascript
vuejs使用FormData实现ajax上传图片文件
Aug 08 #Javascript
基于Vue实现支持按周切换的日历
Sep 24 #Javascript
JS中正则表达式要注意lastIndex属性
Aug 08 #Javascript
vue+mockjs模拟数据实现前后端分离开发的实例代码
Aug 08 #Javascript
React Native如何消除启动时白屏的方法
Aug 08 #Javascript
react native带索引的城市列表组件的实例代码
Aug 08 #Javascript
You might like
Linux下将excel数据导入到mssql数据库中的方法
2010/02/08 PHP
php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
2014/06/19 PHP
php实现常见图片格式的水印和缩略图制作(面向对象)
2016/06/15 PHP
thinkPHP多域名情况下使用memcache方式共享session数据的实现方法
2016/07/21 PHP
PHP中TP5 上传文件的实例详解
2017/07/31 PHP
Javascript实例教程(19) 使用HoTMetal(7)
2006/12/23 Javascript
javascript第一课
2007/02/27 Javascript
Javascript核心读书有感之语句
2015/02/11 Javascript
深入理解JavaScript系列(22):S.O.L.I.D五大原则之依赖倒置原则DIP详解
2015/03/05 Javascript
谈谈encodeURI和encodeURIComponent以及escape的区别与应用
2015/11/24 Javascript
jQuery实现点击任意位置弹出层外关闭弹出层效果
2016/10/19 Javascript
详解nodejs微信公众号开发——4.自动回复各种消息
2017/04/11 NodeJs
微信小程序动态增加按钮组件
2018/09/14 Javascript
基于Vue2实现简易的省市区县三级联动组件效果
2018/11/05 Javascript
JS typeof fn === 'function' &amp;&amp; fn()详解
2020/08/22 Javascript
Python读写Excel文件的实例
2013/11/01 Python
python实现统计代码行数的方法
2015/05/22 Python
Python实现的下载网页源码功能示例
2017/06/13 Python
基于Python Numpy的数组array和矩阵matrix详解
2018/04/04 Python
对pandas中Series的map函数详解
2018/07/25 Python
Python中xml和json格式相互转换操作示例
2018/12/05 Python
使用numpngw和matplotlib生成png动画的示例代码
2021/01/24 Python
Html5中localStorage存储JSON数据并读取JSON数据的实现方法
2017/02/13 HTML / CSS
美国领先的精品家居照明和装饰产品在线零售商:LightsOnline.com
2018/01/23 全球购物
ToysRus日本官网:玩具反斗城
2018/09/08 全球购物
荷兰照明、灯具和配件网上商店:dmlights
2019/08/25 全球购物
创意爱尔兰礼物:Creative Irish Gifts
2020/01/29 全球购物
英国珠宝网站Argento: PANDORA、Olivia Burton和Nomination等
2020/05/08 全球购物
五一服装活动方案
2014/01/11 职场文书
群众路线教育党课主持词
2014/04/01 职场文书
放飞梦想演讲稿600字
2014/08/26 职场文书
预备党员对照检查材料思想汇报
2014/09/24 职场文书
家长学校教学计划
2015/01/19 职场文书
2016教师年度考核评语大全
2015/12/01 职场文书
委托开发合同书(标准版)
2019/08/07 职场文书
CSS3实现列表无限滚动/轮播效果
2021/06/23 HTML / CSS