uniapp 图片上传与展示

项目场景:

uniapp 图片 上传 阿里 OSS 对象存储


需求描述:

H5移动端开发中需要用户上传图片头像、身份证件等需求时。需要将图片上传至阿里oss中存储,并且下载到当前页面进行展示。


解决方案:

代码如下:

需要用到的依赖包:

npm install ali-oss --save 
npm install lrz --save

创建一个 upload.js 文件:

const OSS = require("ali-oss"); //引入安装包;
const lrz = require('lrz');

//配置 阿里 oss 存储对应的 bucket 桶
var client = new OSS({
	region: "oss-cn-beijing", //指申请OSS服务时的地域
	endpoint: "https://oss-cn-beijing.aliyuncs.com", //指定为HTTPS,也可以是IP的形式 region将会被忽略
	accessKeyId: "xxxxxxxxxxxxxxxxxx", //  填写你的accessKeyId
	accessKeySecret: "xxxxxxxxxxxxxxxxxxxxx", // 填写你的accessKeySecret
	bucket: "xxxx", // 桶的名称
	secure: true // 配合region使用。如果指定secure为true,则使用HTTPS访问。
});

// 阿里云上传图片

// e : 文件对象,filename:存储文件名,tag:识别当前事件的种类,配合fn使用,imgpath:图片路径,fn:回调函数

export function uploadImg(e, filename, tag, imgpath, fn) {
	uni.showLoading({
		title: '正在上传...'
	});
	if (e.tempFiles.length == 0) {
	uni.hideLoading();
	uni.showToast({
			title:'未找到图片',
			icon:'none'
		})
	};
	// 检测图片大小
	let file = e.tempFiles[0];
	if (file.size > 15728640) { // 15M  
		uni.showToast({
			title: "您上传的图片文件过大,请重新上传!",
			icon: "none"
		});
		return false
	}
	lrz(file, {
		width: 500,
	}).then(function(res) {
		let base64 = res.base64;
		let blob = convertBase64UrlToBlob(base64);
		let r = Math.random().toString(16).substr(2);
		let time = new Date(),
			y, m, d;
		y = time.getFullYear();
		m = String(time.getMonth() + 1).length === 2 ? (time.getMonth() + 1) : "0" + (time.getMonth() + 1);
		d = String(time.getDate()).length === 2 ? (time.getDate()) : "0" + time.getDate();
		let dfilefold = y + m + d; // 创建时间文件夹
		let name;
		if (imgpath.indexOf(filename) != -1) {
			let tmps = imgpath.split(filename)[1].split('?')[0]; // 获取时间戳
			name = filename + tmps;
		} else {
			name = filename + dfilefold + '/' + r;
		}
		// 上传图片
		client.put(name, blob).then(result => {
			// 上传成功 ;
			uni.hideLoading();
			// 得到图片在oss中的url地址;
			let path = result.url;
			fn(tag, path);
		}).catch(err => {
			console.log(err)
			uni.showToast({
				title: "图上传失败,请重试!",
				icon: "none"
			})
		});
	})
}

// 辅助函数 
function convertBase64UrlToBlob(urlData) {
	var bytes = window.atob(urlData.split(',')[1]); //去掉url的头,并转换为byte
	//处理异常,将ascii码小于0的转换为大于0
	var ab = new ArrayBuffer(bytes.length);
	var ia = new Uint8Array(ab);
	for (var i = 0; i < bytes.length; i++) {
		ia[i] = bytes.charCodeAt(i);
	}
	return new Blob([ab], {
		type: 'image/png'
	});
};

在uniapp 项目组件中

<template>
	<view>
		<view>
			<image class="" :src="idImage1" mode="aspectFit" v-if="idImage1"></image>
			<text class="" style="font-size: 100rpx;"@tap="uploadImgfn('myImage/', 1, idImage1)" v-else />
		</view>
		<view>
			<image class="" :src="idImage1" mode="aspectFit" v-if="idImage2"></image>
			<text class="" style="font-size: 100rpx;"@tap="uploadImgfn('myImage/', 2, idImage2)" v-else />
		</view>
		......
	</view>
</template>
<script>
	// 引入方法;
	import {uploadImg} from "../../../utils/upload.js";
	data() {
			return {
				idImage1: " ", // 图片1
				idImage2:'' '', //  图片2
				idImage3:'' '', //  图片3
			};
		},
		
	methods:{
		uploadImgfn(filename, tag, imgpath) {
				let that = this;
				// 选择图片
				uni.chooseImage({
					success: (res) => {
						console.log(res);
						// 调用方法,上传图片
						uploadImg(res, filename, tag, imgpath, function(tag, path) {
							// 展示上传的图片
							if (tag == 1) {
								that.idImage1 = path + "?" + Date.now();
							} else if (tag == 2) {
								that.idImage1 = path + "?" + Date.now();
							} else if (tag == 3) {
								that.idImage3 = path + "?" + Date.now();
							}
						})
					}
				});
			},
	}
</script>

优化部分

感兴趣的小伙伴可以尝试一下封装成Promise对象,这样就用传递回调函数fn,也不用传递tag参数。在.then()就可以给idImage进行赋值 url

有更好、更加简洁的方法希望大家能给我提出宝贵的意见或链接。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shaoin_2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值