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 相关文章推荐
URL编码转换,escape() encodeURI() encodeURIComponent()
Dec 27 Javascript
轻量级 JS ToolTip提示效果
Jul 20 Javascript
原生javascript实现Tab选项卡切换功能
Jan 12 Javascript
JavaScript数组随机排列实现随机洗牌功能
Mar 19 Javascript
JavaScript中var关键字的使用详解
Aug 14 Javascript
浅析如何利用angular结合translate为项目实现国际化
Dec 08 Javascript
node错误处理与日志记录的实现
Dec 24 Javascript
关于微信公众号开发无法支付的问题解决
Dec 28 Javascript
node中使用log4js4.x版本记录日志的方法
Aug 20 Javascript
ES2020 新特性(种草)
Jan 12 Javascript
node+multer实现图片上传的示例代码
Feb 18 Javascript
JS新手入门数组处理的实用方法汇总
Apr 07 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类的自动加载操作实例详解
2016/09/28 PHP
PHP实现的杨辉三角求解算法分析
2019/03/11 PHP
理解Javascript_08_函数对象
2010/10/15 Javascript
apycom出品的jQuery精美菜单破解方法
2011/02/18 Javascript
如何将一个String和多个String值进行比较思路分析
2013/04/22 Javascript
JavaScript计算字符串中每个字符出现次数的小例子
2013/07/02 Javascript
js中settimeout方法加参数的使用实例
2014/02/27 Javascript
原生javascript模仿win8等待提示圆圈进度条
2014/04/24 Javascript
JavaScript之数组(Array)详解
2015/04/01 Javascript
javascript实现鼠标移到Image上方时显示文字效果的方法
2015/08/07 Javascript
JS+CSS实现大气清新的滑动菜单效果代码
2015/10/22 Javascript
JavaScript观察者模式(经典)
2015/12/09 Javascript
JavaScript过滤字符串中的中文与空格方法汇总
2016/03/07 Javascript
AngularJS模板加载用法详解
2016/11/04 Javascript
Javascript中Promise的四种常用方法总结
2017/07/14 Javascript
Vue不能检测到Object/Array更新的情况的解决
2018/06/26 Javascript
vue实现分页的三种效果
2020/06/23 Javascript
js canvas实现俄罗斯方块
2020/10/11 Javascript
vue 使用class创建和清除水印的示例代码
2020/12/25 Vue.js
python 开发的三种运行模式详细介绍
2017/01/18 Python
Python常见异常分类与处理方法
2017/06/04 Python
Python中的探索性数据分析(功能式)
2017/12/22 Python
Python八大常见排序算法定义、实现及时间消耗效率分析
2018/04/27 Python
Python实现矩阵相乘的三种方法小结
2018/07/26 Python
python游戏地图最短路径求解
2019/01/16 Python
获取CSDN文章内容并转换为markdown文本的python
2020/09/06 Python
python基于opencv实现人脸识别
2021/01/04 Python
详解Python之Scrapy爬虫教程NBA球员数据存放到Mysql数据库
2021/01/24 Python
Python中Pyspider爬虫框架的基本使用详解
2021/01/27 Python
办公室文秘自我评价
2013/09/21 职场文书
人事主管岗位职责
2014/01/30 职场文书
旷课检讨书500字
2014/10/14 职场文书
2014年财务工作总结与计划
2014/12/08 职场文书
英语导游词
2015/02/13 职场文书
2016大学生求职自荐信范文
2016/01/28 职场文书
python 用递归实现通用爬虫解析器
2021/04/16 Python