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 相关文章推荐
对textarea框的代码调试,而且功能上使用非常方便,酷
Jun 30 Javascript
JavaScript 密码强度判断代码
Sep 05 Javascript
JavaScript 数组详解
Oct 10 Javascript
JS应用正则表达式转换大小写示例
Sep 18 Javascript
jQuery Mobile框架中的表单组件基础使用教程
May 17 Javascript
Vue方法与事件处理器详解
Dec 01 Javascript
node.js学习之交互式解释器REPL详解
Dec 08 Javascript
jQuery实现拖动剪裁图片作为头像
Dec 28 Javascript
最常用的jQuery表单验证(简单)
May 23 jQuery
Ant Design Pro 下实现文件下载的实现代码
Dec 03 Javascript
vue动态渲染svg、添加点击事件的实现
Mar 13 Javascript
如何使用JavaScript检测空闲的浏览器选项卡
May 28 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类的注册与自动加载
2013/07/05 PHP
JavaScript Cookie显示用户上次访问的时间和次数
2009/12/08 Javascript
javascript suggest效果 自动完成实现代码分享
2012/02/17 Javascript
js 取时间差去掉周六周日实现代码
2012/12/25 Javascript
jquery实现checkbox 全选/全不选的通用写法
2014/02/22 Javascript
Jquery实现自定义弹窗示例
2014/03/12 Javascript
图片旋转、鼠标滚轮缩放、镜像、切换图片js代码
2020/12/13 Javascript
全国省市二级联动下拉菜单 js版
2016/05/10 Javascript
js HTML5多媒体影音播放
2016/10/17 Javascript
详解在不使用ssr的情况下解决Vue单页面SEO问题
2018/11/08 Javascript
Vuex的初探与实战小结
2018/11/26 Javascript
layui自定义插件citySelect实现省市区三级联动选择
2019/07/26 Javascript
NodeJS 文件夹拷贝以及删除功能
2019/09/03 NodeJs
vue 使用高德地图vue-amap组件过程解析
2019/09/07 Javascript
[47:42]完美世界DOTA2联赛PWL S2 GXR vs Ink 第一场 11.19
2020/11/20 DOTA
Python HTMLParser模块解析html获取url实例
2015/04/08 Python
python引入导入自定义模块和外部文件的实例
2017/07/24 Python
python使用openpyxl库修改excel表格数据方法
2018/05/03 Python
python三方库之requests的快速上手
2019/03/04 Python
pandas对dataFrame中某一个列的数据进行处理的方法
2019/07/08 Python
Django项目使用CircleCI的方法示例
2019/07/14 Python
Django对接支付宝实现支付宝充值金币功能示例
2019/12/17 Python
Pytorch保存模型用于测试和用于继续训练的区别详解
2020/01/10 Python
keras绘制acc和loss曲线图实例
2020/06/15 Python
推荐技术人员一款Python开源库(造数据神器)
2020/07/08 Python
PIP和conda 更换国内安装源的方法步骤
2020/09/21 Python
倩碧美国官网:Clinique美国
2016/07/20 全球购物
物流仓管员岗位职责
2013/12/04 职场文书
公积金转移接收函
2014/01/11 职场文书
优秀交警事迹材料
2014/01/26 职场文书
硕士学位申请报告
2015/05/15 职场文书
小学一年级语文教学反思
2016/03/03 职场文书
高三英语教学反思
2016/03/03 职场文书
2016年村党支部公开承诺书
2016/03/24 职场文书
python中如何对多变量连续赋值
2021/06/03 Python
MySQL系列之十二 备份与恢复
2021/07/02 MySQL