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 Ajax.ashx 高效分页实现代码
Oct 20 Javascript
通过JavaScript控制字体大小的代码
Oct 04 Javascript
jquery 面包屑导航 具体实现
Jun 05 Javascript
JavaScript实现的MD5算法完整实例
Feb 02 Javascript
在html中引入外部js文件,并调用带参函数的方法
Oct 31 Javascript
php 修改密码实现代码
May 24 Javascript
详解react-webpack2-热模块替换[HMR]
Aug 03 Javascript
Element-ui之ElScrollBar组件滚动条的使用方法
Sep 14 Javascript
对angular 监控数据模型变化的事件方法$watch详解
Oct 09 Javascript
详解vue项目中实现图片裁剪功能
Jun 07 Javascript
vue实现图片懒加载的方法分析
Feb 05 Javascript
详解vue父子组件状态同步的最佳方式
Sep 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
深入eAccelerator与memcached的区别详解
2013/06/06 PHP
解决PHP4.0 和 PHP5.0类构造函数的兼容问题
2013/08/01 PHP
PHP实现的简单日历类
2014/11/29 PHP
Yii核心组件AssetManager原理分析
2014/12/02 PHP
分享五个PHP7性能优化提升技巧
2015/12/07 PHP
PHP+Session防止表单重复提交的解决方法
2018/04/09 PHP
jquery获取table中的某行全部td的内容方法
2013/03/08 Javascript
JS获取鼠标坐标的实例方法
2013/07/18 Javascript
jQuery Ajax异步处理Json数据详解
2013/11/05 Javascript
基于javascript实现判断移动终端浏览器版本信息
2014/12/09 Javascript
详解AngularJS中自定义指令的使用
2015/06/17 Javascript
jQuery获取DOM节点实例分析(2种方式)
2015/12/15 Javascript
AngularJS基础 ng-cloak 指令简单示例
2016/08/01 Javascript
angularjs 页面自适应高度的方法
2018/01/17 Javascript
如何修改Vue打包后文件的接口地址配置的方法
2020/04/22 Javascript
原生JS实现无缝轮播图片
2020/06/24 Javascript
Python中使用SAX解析xml实例
2014/11/21 Python
Python下实现的RSA加密/解密及签名/验证功能示例
2017/07/17 Python
python模块smtplib实现纯文本邮件发送功能
2018/05/22 Python
Python中实例化class的执行顺序示例详解
2018/10/14 Python
python调用c++传递数组的实例
2019/02/13 Python
详解Python匿名函数(lambda函数)
2019/04/19 Python
python lxml中etree的简单应用
2019/05/10 Python
树莓派安装OpenCV3完整过程的实现
2019/10/10 Python
Python 实现一行输入多个数字(用空格隔开)
2020/04/29 Python
Python 日期与时间转换的方法
2020/08/01 Python
详解pycharm连接远程linux服务器的虚拟环境的方法
2020/11/13 Python
卫校中专生个人自我评价
2013/09/19 职场文书
如何写一份好的英文求职信
2014/03/19 职场文书
物业管理工作方案
2014/05/10 职场文书
2014年秋季开学典礼致辞
2014/08/02 职场文书
法人身份证明书
2014/10/08 职场文书
工程部文员岗位职责
2015/02/04 职场文书
中考百日冲刺决心书
2015/09/22 职场文书
2016年第十四个公民道德宣传日活动总
2016/04/01 职场文书
vue的项目如何打包上线
2022/04/13 Vue.js