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 相关文章推荐
juqery 学习之五 文档处理 包裹、替换、删除、复制
Feb 11 Javascript
利用javascript的面向对象的特性实现限制试用期
Aug 04 Javascript
jquery Ajax 实现加载数据前动画效果的示例代码
Feb 07 Javascript
jquery的ajax跨域请求原理和示例
May 08 Javascript
JavaScript操作Cookie方法实例分析
May 27 Javascript
JavaScript驾驭网页-CSS与DOM
Mar 24 Javascript
Bootstrap CSS组件之大屏幕展播
Dec 17 Javascript
简述jQuery Easyui一些用法
Aug 01 jQuery
JS实现的判断方法、变量是否存在功能示例
Mar 28 Javascript
vue项目中jsonp跨域获取qq音乐首页推荐问题
May 30 Javascript
JavaScript实现正则去除a标签并保留内容的方法【测试可用】
Jul 18 Javascript
浅析微信小程序自定义日历组件及flex布局最后一行对齐问题
Oct 29 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
PHP学习之数组值的操作
2011/04/17 PHP
ThinkPHP模板之变量输出、自定义函数与判断语句用法
2014/11/01 PHP
php+xml结合Ajax实现点赞功能完整实例
2015/01/30 PHP
php实现递归抓取网页类实例
2015/04/03 PHP
Zend Framework+smarty用法实例详解
2016/03/19 PHP
php使用file函数、fseek函数读取大文件效率对比分析
2016/11/04 PHP
各种常用浏览器getBoundingClientRect的解析
2009/05/21 Javascript
javascript打印html内容功能的方法示例
2013/11/28 Javascript
JavaScript事件委托用法分析
2015/01/24 Javascript
jQuery实现的数值范围range2dslider选取插件特效多款代码分享
2015/08/27 Javascript
Javascript日期格式化format函数的使用方法
2016/08/30 Javascript
动态加载css方法实现和深入解析
2017/01/18 Javascript
Bootstrap table学习笔记(2) 前后端分页模糊查询
2017/05/18 Javascript
Node.js中使用mongoose操作mongodb数据库的方法
2017/09/12 Javascript
40行代码把Vue3的响应式集成进React做状态管理
2020/05/20 Javascript
如何使用JavaScript检测空闲的浏览器选项卡
2020/05/28 Javascript
vue-cli4.0多环境配置变量与模式详解
2020/12/30 Vue.js
Python设计模式之观察者模式实例
2014/04/26 Python
Python 序列化 pickle/cPickle模块使用介绍
2014/11/30 Python
Python常见字符串操作函数小结【split()、join()、strip()】
2018/02/02 Python
Python统计纯文本文件中英文单词出现个数的方法总结【测试可用】
2018/07/25 Python
Anaconda2 5.2.0安装使用图文教程
2018/09/19 Python
python中eval与int的区别浅析
2019/08/11 Python
tensorflow对图像进行拼接的例子
2020/02/05 Python
python标准库OS模块函数列表与实例全解
2020/03/10 Python
浅谈python 类方法/静态方法
2020/09/18 Python
python pymysql库的常用操作
2020/10/16 Python
德国珠宝和手表在线商店:VALMANO
2019/03/24 全球购物
世界顶级户外运动品牌折扣网站:LeftLane Sports
2019/06/12 全球购物
常用UNIX 命令(Linux的常用命令)
2015/12/26 面试题
电钳专业个人求职信
2014/01/04 职场文书
单位在职证明书
2014/09/11 职场文书
大一工商管理职业生涯规划:有梦最美,行动相随
2014/09/18 职场文书
环卫处个人工作总结
2015/03/04 职场文书
节约用电倡议书
2015/04/28 职场文书
2015年大学辅导员工作总结
2015/05/12 职场文书