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 相关文章推荐
用 JavaScript 迁移目录
Dec 18 Javascript
JS获取鼠标坐标的实例方法
Jul 18 Javascript
JS实现鼠标单击与双击事件共存
Mar 08 Javascript
jquery text()方法取标签中的文本
Jul 25 Javascript
浅谈jQuery中的事件
Mar 23 Javascript
浅谈javascript的分号的使用
May 12 Javascript
JavaScript prototype属性详解
Oct 25 Javascript
详解express + mock让前后台并行开发
Jun 06 Javascript
学习jQuery中的noConflict()用法
Sep 28 jQuery
JavaScript创建对象的四种常用模式实例分析
Jan 11 Javascript
vue单页面在微信下只能分享落地页的解决方案
Apr 15 Javascript
vue中如何实现后台管理系统的权限控制的方法步骤
Sep 05 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
使用ThinkPHP+Uploadify实现图片上传功能
2014/06/26 PHP
PHP的Yii框架中Model模型的学习教程
2016/03/29 PHP
PHP+Mysql无刷新问答评论系统(源码)
2016/12/20 PHP
使用jQuery validate 验证注册表单实例演示
2013/03/25 Javascript
JS 两日期相减,获得天数的小例子(兼容IE,FF)
2013/07/01 Javascript
7个JS基础知识总结
2014/03/05 Javascript
学习JavaScript设计模式(封装)
2015/11/26 Javascript
JQuery导航菜单选择特效
2016/04/11 Javascript
微信小程序 地图(map)实例详解
2016/11/16 Javascript
BootStrap select2 动态改变值的方法
2017/02/10 Javascript
jQuery、zepto、js常用小技巧
2017/02/12 Javascript
react-native-fs实现文件下载、文本存储的示例代码
2017/09/22 Javascript
vue-router实现tab标签页(单页面)详解
2017/10/17 Javascript
Vue 第三方字体图标引入 Font Awesome的方法
2018/09/28 Javascript
Koa 使用小技巧(小结)
2018/10/22 Javascript
微信小程序 wx.getUserInfo引导用户授权问题实例分析
2020/03/09 Javascript
vscode中Vue别名路径提示的实现
2020/07/31 Javascript
Python3搜索及替换文件中文本的方法
2015/05/22 Python
Python实现将数据框数据写入mongodb及mysql数据库的方法
2018/04/02 Python
python 高效去重复 支持GB级别大文件的示例代码
2018/11/08 Python
python实现动态创建类的方法分析
2019/06/25 Python
在Tensorflow中实现leakyRelu操作详解(高效)
2020/06/30 Python
详解移动端HTML5音频与视频问题及解决方案
2018/08/22 HTML / CSS
Html5大文件断点续传实现方法
2015/12/05 HTML / CSS
Gina Bacconi官网:吉娜贝康尼连衣裙和礼服
2018/04/24 全球购物
酒店总经理欢迎词
2014/01/08 职场文书
我的小天地教学反思
2014/04/30 职场文书
大专学生求职自荐信
2014/07/06 职场文书
2014年绩效考核工作总结
2014/12/11 职场文书
煤矿隐患排查制度
2015/08/05 职场文书
小学体育课教学反思
2016/02/16 职场文书
800字作文之大雪
2019/12/04 职场文书
python3 hdf5文件 遍历代码
2021/05/19 Python
Vue实现tab导航栏并支持左右滑动功能
2021/06/28 Vue.js
HTML中的表格元素介绍
2022/02/28 HTML / CSS
MySQL中rank() over、dense_rank() over、row_number() over用法介绍
2022/03/23 MySQL