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 相关文章推荐
初窥JQuery-Jquery简介 入门了解篇
Nov 25 Javascript
用客户端js实现带省略号的分页
Apr 27 Javascript
浅谈JavaScript Date日期和时间对象
Dec 29 Javascript
基于jquery实现百度新闻导航菜单滑动动画
Mar 15 Javascript
基于socket.io+express实现多房间聊天
Mar 17 Javascript
jQuery多文件异步上传带进度条实例代码
Aug 16 Javascript
JS求解三元一次方程组值的方法
Jan 03 Javascript
JS原生带小白点轮播图实例讲解
Jul 22 Javascript
vue-cli中打包图片路径错误的解决方法
Oct 26 Javascript
微信小程序中this.data与this.setData的区别详解
Sep 17 Javascript
多个vue子路由文件自动化合并的方法
Sep 03 Javascript
vue使用微信扫一扫功能的实现代码
Apr 11 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
JAVA/JSP学习系列之二
2006/10/09 PHP
比较strtr, str_replace和preg_replace三个函数的效率
2013/06/26 PHP
php中怎么搜索相关联数组键值及获取之
2013/10/17 PHP
php计算税后工资的方法
2015/07/28 PHP
php实现的错误处理封装类实例
2017/06/20 PHP
javascript 年月日联动实现核心代码
2009/12/21 Javascript
JavaScript插入动态样式实现代码
2012/02/22 Javascript
jquery select 设置默认选中的示例代码
2014/02/07 Javascript
jquery 实现两级导航菜单附效果图
2014/03/07 Javascript
JavaScript实现找质数代码分享
2015/03/24 Javascript
Angular发布1.5正式版,专注于向Angular 2的过渡
2016/02/18 Javascript
JS获取子窗口中返回的数据实现方法
2016/05/28 Javascript
ES6通过babel转码使用webpack使用import关键字
2016/12/13 Javascript
JavaScript工具库之Lodash详解
2019/06/15 Javascript
Vue学习之axios的使用方法实例分析
2020/01/06 Javascript
Node.js API详解之 dns模块用法实例分析
2020/05/15 Javascript
[01:30]DOTA2上海特锦赛现场采访 Loda倾情献唱
2016/03/25 DOTA
[01:06]DOTA2小知识课堂 Ep.01 TP出门不要忘记帮队友灌瓶哦
2019/12/05 DOTA
在Python的Django框架中获取单个对象数据的简单方法
2015/07/17 Python
python pyheatmap包绘制热力图
2018/11/09 Python
Python3.8中使用f-strings调试
2019/05/22 Python
Django restful framework生成API文档过程详解
2020/11/12 Python
webView加载html图片遇到的问题解决
2019/10/08 HTML / CSS
Erwin Müller穆勒家居瑞士官网:您整个家庭的邮购公司
2019/12/28 全球购物
沙特阿拉伯排名第一的在线时尚购物应用程序:1Zillion
2020/08/08 全球购物
班组长竞聘书
2014/03/31 职场文书
教师党员先进性教育自我剖析材料思想汇报
2014/09/24 职场文书
公务员政审个人总结
2015/02/12 职场文书
2015年电话销售工作总结范文
2015/04/20 职场文书
于丹论语心得观后感
2015/06/15 职场文书
英文投诉信格式
2015/07/03 职场文书
2016年小学端午节活动总结
2016/04/01 职场文书
《追风筝的人》:人心中的成见是座大山,但请不忘初心
2019/11/15 职场文书
JavaScript 实现页面滚动动画
2021/04/24 Javascript
Java并发编程之详解CyclicBarrier线程同步
2021/06/23 Java/Android
javascript函数式编程基础
2021/09/15 Javascript