首页 > 技术文章 > UniApp+uView实现表单中的图片批量上传

railgunSE 2021-06-24 23:34 原文

UniApp+uView实现表单中的图片批量上传

技术概述

团队项目的需求是:用户在投诉的时候可以拍摄、多选上传最多5张的照片,达到上限时,隐藏上传按钮;用户可以预览、删除所选图片,添加或删除后的图片数和预览小图要及时、正确地反映到界面上;最终图片与投诉文字一起提交。
难点:在已有组件的基础上改进为自己想要的样子。

技术详述

我在团队开发中是否担任了小程序的前端开发,因此以下叙述没有涉及到图片上传的后端处理。
使用的是uView前端框架中的u-upload组件,使用方法可以参考uView的官方文档:Upload组件官方文档说明。在uni-app插件市场可以下载到uview-ui安装包,具体配置方法不作赘述。解压后在components下可以找到组件源码,注释里给出了更详细的参数配置方法以供参考,也可以阅读其实现代码加深理解。
image

  • 界面代码

直接引用组件,参照官方文档,结合自己的需求修改各种参数,例如上传图片的按钮、上传时的遮罩层、删除按钮等都是可以进行个性化配置的。这里我们将自动上传打开(auto-upload="true"),这样用户选择完图片后系统即返回一个url。等待用户将投诉文本填写完毕,再将图片url与文字一并提交。

image

  • 数据存储与部分参数配置

如图所示,action为服务器地址,form为表单上传的数据结构(是一个model),其中携带两个参数,反馈文本与图片url。fileList是组件自带的图片存放列表,imageList则是我们额外使用的用于传递图片url集合的数组。

image

  • 处理函数
  1. on-list-change:当内部文件列表被加入文件、移除文件,或手动调用clear方法时触发.返回(lists, name),lists为内部文件变化之后的列表,name为通过props传递的index参数。
  2. on-success:图片上传成功时触发,data为服务器返回的数据。
  3. on-remove:移除图片时触发,name为通过props传递的index参数。

函数都放在methods里,并在界面代码中与事件绑定。上传组件请求后端服务器后接收返回的图片url,组件会自动更新预览列表,我们则将url以字符串的形式存入到表单的提交参数中,剩下的切割等工作交给后端或者需要显示反馈图片的Web端处理。
onListChange:这里我们直接获取所返回的lists的长度得到实时选择图片数。
onSuccess:具体的说明都在注释中给出。
onRemove:删除图片时,通过slice切分,准确获得指定下标图片被删除后的结果。

在数组中 slice(i,[j])
i为开始截取的索引值,负数代表从末尾算起的索引值,-1为倒数第一个元素
j为结束的索引值,缺省时则获取从i到末尾的所有元素
参数返回:
返回索引值从i到j的数组,原数组不改变

image

  • 流程图

image

问题和解决过程

  • 坑1:开发过程中会出现如下情况:在小程序开发版与体验版的调试过程中,图片上传没有问题;但发布后的线上版本,图片上传请求后端接口失败。
    原因:微信小程序里如果涉及到文件上传、下载等,发布上线版本时,需要到微信公众号官网,小程序开发管理里面,配置服务器域名,才能使相关功能的正常运行。就比如图片上传。
    image

  • 坑2:允许的图片后缀可以主动配置,默认为['png', 'jpg', 'jpeg', 'webp', 'gif'],但部分手机型号会出现图片后缀为大写的情况,因此需要主动加上,否则可能也会导致上传失败。
    limitType: ['png', 'jpg', 'jpeg', 'webp', 'gif', 'JPG', 'PNG', 'JPEG', 'GIF', 'WEBP'],

  • 坑3:清空表单内容时最好将下面几句一并写上,不然可能会出现部分数据没有重置的情况。
    image

  • 坑4:记得使用并且善用JSON.stringify,否则常常会得到一个空串。遇到时就可以检查是否忘记了这一步。还有可能是服务器返回的数据结构与你写的获取代码不一致,比如服务器返回的是data.data.pictureUrl,包了两层data,只写data.pictureUrl的话就漏了一层。

  • 坑5:处理添加与删除图片逻辑的时候一定要小心,参照上图代码,善用控制台测试。否则该组件会出现添加或删除图片后多出一张空白预览图的情况。

  • 坑6:表单组件u-form的填写规则(例如填写字数上限)要在onReady()生命周期中设置,否则无效。

<u-form :model="form" @submit="submit" :rules="rules" ref="uForm" >

this.$refs.uForm.setRules(this.rules);

image

总结

uView是一个基于UniApp的开源前端模板,其存在本身较“新”,因此肯定存在着bug与设计上的不足。在使用其中的组件时势必会遇到不少问题,可能百度都难以找到与自己的情况完全相符的解决方法,这时候就可以多多仔细阅读官方文档与源代码,了解其内部逻辑;如果实在无法解决就先跳脱出去,想想是不是前端代码以外的问题,或者是否有替代方案。

参考

  1. Upload组件官方文档说明
  2. uview-ui下载地址
  3. 小程序前端Vue里使用u-upload进行多图片上传

推荐阅读