• 【关于我接触了Uview的Upload】——单图上传,多图上传,遇到的问题总结、直传阿里云Oss


    Uview的Upload组件

    前言

    有很长一段时间没有更新了,由于工作的繁忙导致没有时间写博客,今天在做到公司特殊场景需要用到上传组件并直传阿里云Oss,这里简单讲讲我在完成前端项目中使用到Uview的Upload遇到的问题以及我是如何解决,直传阿里云Oss的。

    版本

     uview-ui: "^2.0.31"
     node:14.18.1
    
    • 1
    • 2

    官方地址

    https://www.uviewui.com/components/upload.html
    
    • 1

    简单的使用方法

    这里如果你单纯的想拿到上传之后的url的话,可以直接看官方实例:

    使用

    在这里插入图片描述

    <script>
    	export default {
    		data() {
    			return {
    				fileList1: [],
    			}
    		},
    		methods:{
    			// 删除图片
    			deletePic(event) {
    				this[`fileList${event.name}`].splice(event.index, 1)
    			},
    			// 新增图片
    			async afterRead(event) {
    				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
    				let lists = [].concat(event.file)
    				let fileListLen = this[`fileList${event.name}`].length
    				lists.map((item) => {
    					this[`fileList${event.name}`].push({
    						...item,
    						status: 'uploading',
    						message: '上传中'
    					})
    				})
    				for (let i = 0; i < lists.length; i++) {
    					const result = await this.uploadFilePromise(lists[i].url)
    					let item = this[`fileList${event.name}`][fileListLen]
    					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
    						status: 'success',
    						message: '',
    						url: result
    					}))
    					fileListLen++
    				}
    			},
    			uploadFilePromise(url) {
    				return new Promise((resolve, reject) => {
    					let a = uni.uploadFile({
    						url: 'http://192.168.2.21:7001/upload', // 仅为示例,非真实的接口地址
    						filePath: url,
    						name: 'file',
    						formData: {
    							user: 'test'
    						},
    						success: (res) => {
    							setTimeout(() => {
    								resolve(res.data.data)
    							}, 1000)
    						}
    					});
    				})
    			},
    		}
    
    	}
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    注意点

    这里的:fileList=fileList1要与data中的fileList1一一对应,不能乱写,具体原因可以继续看下去。
    他其实本质是对uniapp的upload的再次封装!

    结果

    我们使用这个组件上传后,我们可以打印出返回的event
    在这里插入图片描述
    这里是结果,

    如果是单图上传,我们可以发现,我们的图片存储在了一个对象里,里面的file中有我们图片的名称,大小,以及临时存储路径,如果你传给后端只需要传链接,那么看这里就可以结束了,剩下的就是格式的问题,看后端需要什么样的图片格式,对blob流进行相应的转化即可,

    如果是多图上传,那么file会有多个对象,也是同样的道理。
    在这里插入图片描述

    直传阿里云oss

    这里属于是特殊的场景需求了,有需要的小伙伴可以看下去。
    如果改造Uview的Upload来进行前端直传阿里云Oss
    我们仔细观察官方实例,其实可以发现,上传的核心代码是在这里:

    const result = await this.uploadFilePromise(lists[i].url)
    
    • 1
    		uploadFilePromise(url) {
    				return new Promise((resolve, reject) => {
    					let a = uni.uploadFile({
    						url: 'http://192.168.2.21:7001/upload', // 仅为示例,非真实的接口地址
    						filePath: url,
    						name: 'file',
    						formData: {
    							user: 'test'
    						},
    						success: (res) => {
    							setTimeout(() => {
    								resolve(res.data.data)
    							}, 1000)
    						}
    					});
    				})
    			},
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    通过循环遍历图片数组,将图片调用uploadFilePromise方法进行上传,我们拿到图片的临时url,使用uni.uploadFile方法进行上传图片,所以他其实本质是对uni的上传方法进行二次封装,那么清楚原理之后,我们进行改造,要直传阿里云Oss,首先我们得获得阿里云Oss的权限,这里一般情况都是通过后端拿到临时阿里云Oss访问权限,也就是我们所说的密钥

    阿里云Oss官方地址

    https://help.aliyun.com/document_detail/111265.html?spm=a2c4g.11186623.0.0.6f6d110aTbK5Vs
    
    • 1

    我们需要的就是这些
    在这里插入图片描述

    最重要的其实就是这两个,访问阿里云Oss,当然还有其他很多的参数,这个看具体的业务场景需求,可能还需要其他的参数,但是密钥是必须的,所以要想上传阿里云Oss,就得先获得权限,下面会解释遇到的坑。

    accessid:密钥ID
    signature:密钥
    policy
    
    • 1
    • 2
    • 3

    方法

    我们改造官方示例:

    	let a = uni.uploadFile({
    						url: your.host, // 仅为示例,非真实的接口地址,这里的地址是传阿里云oss的地址
    						filePath: url,		//url就是你拿到的图片url,这里不用动
    						fileType: type, //类型 ,这里是必填的,直接拿event里面的type即可
    						name: 'file',  //不用动
    						formData: {
    							key: this.key,  //这里是指你存放到阿里云oss的路径
    							region: 'oss-cn-shenzhen',  //这里是阿里云需要的地域
    							policy: this.oss.policy, //签名
    							signature: this.oss.signature, //密钥
    							OSSAccessKeyId: this.oss.accessid, //id
    						},
    						success: (res) => {
    							// setTimeout(() => {
    							//   resolve(res.data.data)
    							// }, 1000)
    							resolve(res.data.data)
    							//成功的回调
    							}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    遇到的问题

    权限问题

    在这里插入图片描述
    我们发现,虽然返回的是uploadFile:ok,但是Oss中并没有,我们仔细看,其实还是失败的,是errMsg,这种一般是权限问题,可以跟后端沟通配合解决,报错中也会提示究竟是哪个权限有问题。

    跨域问题

    在这里插入图片描述

    跨域的问题在浏览器中经常会有,这个网上的配置有很多,你可以参考一下,当然,最简单无脑的方式,你可以直接使用HbuilderX的内置浏览器,当然体验不是特别好,但是没有跨域的问题!

    页面中使用多个Upload,出现的问题

    我在使用官方示例没有问题,但当我使用多个Upload进行上传就出现了问题,找不到fileList
    在这里插入图片描述
    后来我发现了,官方实例中的这一句

    let fileListLen = this[`fileList${event.name}`].length
    
    • 1

    这是Es6的模板字符串,跟我一样看不懂的,属实得多看看基础了

    this[`fileList${event.name}`]
    
    • 1

    他其实是这个this.fileList+event.name
    所以,注意:我们的upload中的name:fileList="xxx",不能自己去乱定义,你使用官方的示例,那就得遵守规则,这个name的值,其实就是event.name的值,如果你的name为“1”,那么:fileList="fileList1"就必须得这么写
    同理可得:

    <u-upload
    		:fileList="fileList1"
    		@afterRead="afterRead"
    		@delete="deletePic"
    		name="1"
    		multiple
    		:maxCount="10"
    	></u-upload>
    
    <u-upload
    		:fileList="fileList2"
    		@afterRead="afterRead"
    		@delete="deletePic"
    		name="2"
    		multiple
    		:maxCount="10"
    	></u-upload>
    
    	<u-upload
    		:fileList="fileList3"
    		@afterRead="afterRead"
    		@delete="deletePic"
    		name="3"
    		multiple
    		:maxCount="10"
    	></u-upload>
    
    data() {
    			return {
    				fileList1: [],
    				fileList2: [],
    				fileList3: [],
    			}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    你就得这么写,所以一开始使用为什么觉得这么命名那么奇怪,想自定义命名的同学们,那就得体验一下报错的快感了。

    后言

    我是前端小白,如果你觉得这篇文章有哪些不足之后,或者还遇到什么奇怪的问题,可以在评论区留言

  • 相关阅读:
    含文档+PPT+源码等]精品微信小程序ssm社区心理健康服务平台+后台管理系统|前后分离VUE[包运行成功]微信小程序项目源码Java毕业设计
    springboot实现自定义注解限流
    Python生成器:
    linux ssh 禁止指定用户通过ssh登录
    Vue——webpack项目(没有安装vue-cli脚手架时)解决请求项目启动问题、跨域问题和请求转发报404的问题
    Ubuntu 20.04安装Docker
    java毕业生设计高校毕业生就业满意度调查统计系统计算机源码+系统+mysql+调试部署+lw
    2.14 PE结构:地址之间的转换
    promise详细的适用
    MTK平台Metadata的加载(1)——Metadata介绍
  • 原文地址:https://blog.csdn.net/m0_46983722/article/details/128119584