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 相关文章推荐
js 加载并解析XML字符串的代码
Dec 13 Javascript
通过jQuery打造支持汉字,拼音,英文快速定位查询的超级select插件
Jun 18 Javascript
原生javascript实现Tab选项卡切换功能
Jan 12 Javascript
js随机生成字母数字组合的字符串 随机动画数字
Sep 02 Javascript
JS基于Ajax实现的网页Loading效果代码
Oct 27 Javascript
Js+Ajax,Get和Post在使用上的区别小结
Jun 08 Javascript
Vue.js教程之axios与网络传输的学习实践
Apr 29 Javascript
如何使用pm2快速将项目部署到远程服务器
Mar 12 Javascript
在vue中把含有html标签转为html渲染页面的实例
Oct 28 Javascript
微信小程序服务器日期格式化问题
Jan 07 Javascript
webpack中的模式(mode)使用详解
Feb 20 Javascript
Vue使用v-viewer实现图片预览
Oct 21 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 db类库进行数据库操作
2009/03/19 PHP
php获取本地图片文件并生成xml文件输出具体思路
2013/04/27 PHP
php正则提取html图片(img)src地址与任意属性的方法
2017/02/08 PHP
PHP getDocNamespaces()函数讲解
2019/02/03 PHP
Aster vs Newbee BO3 第三场2.18
2021/03/10 DOTA
JQuery Dialog(JS 模态窗口,可拖拽的DIV)
2010/02/07 Javascript
关于extjs treepanel复选框选中父节点与子节点的问题
2013/04/02 Javascript
使用变量动态设置js的属性名
2014/10/19 Javascript
轻松实现JavaScript图片切换
2016/01/12 Javascript
js表单元素checked、radio被选中的几种方法(详解)
2016/08/22 Javascript
有趣的bootstrap走动进度条
2016/12/01 Javascript
jQuery插件扩展操作入门示例
2017/01/16 Javascript
js下拉菜单生成器dropMenu使用方法详解
2017/08/01 Javascript
layui 表格的属性的显示转换方法
2018/08/14 Javascript
JS/jQuery实现获取时间的方法及常用类完整示例
2019/03/07 jQuery
M2实现Nodejs项目自动部署的方法步骤
2019/05/05 NodeJs
JavaScript位置参数实现原理及过程解析
2020/09/14 Javascript
[02:52]DOTA2新手基础教程 米波
2014/01/21 DOTA
[40:56]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 Liquid vs TNC
2018/04/01 DOTA
基于Pandas读取csv文件Error的总结
2018/06/15 Python
Python Cookie 读取和保存方法
2018/12/28 Python
在python中利用最小二乘拟合二次抛物线函数的方法
2018/12/29 Python
python多任务及返回值的处理方法
2019/01/22 Python
Python 线性回归分析以及评价指标详解
2020/04/02 Python
Python3自定义http/https请求拦截mitmproxy脚本实例
2020/05/11 Python
Python分类测试代码实例汇总
2020/07/23 Python
Python用access判断文件是否被占用的实例方法
2020/12/17 Python
以设计师精品品质提供快速时尚:PopJulia
2018/01/09 全球购物
纽约州一群才华横溢的金匠制作而成:Hearth Jewelry
2019/03/22 全球购物
毕业生个人求职的自我评价
2013/10/28 职场文书
会计电算化专业个人的自我评价
2013/11/24 职场文书
配件采购员岗位职责
2013/12/03 职场文书
电工工作职责范本
2014/02/22 职场文书
河童之夏观后感
2015/06/11 职场文书
MySQL数据库如何给表设置约束详解
2022/03/13 MySQL
Redis特殊数据类型HyperLogLog基数统计算法讲解
2022/06/01 Redis