微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐