uni-app 上传图片

219 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,查看详情

需求:微信小程序上传图片

image.png

开发过程遇到的问题:1.小白阶段的时候不太会封装组件,每个需要上传图片的页面都写了一遍代码,导致代码冗余 2. 封装的组件不灵活 解决方案:封装组件

在components > upload-img > upload-img.vue

1.组件的html代码

<template>
	<view class="uploadImgPage">
		<view class="img-wrap" v-for="(item, index) in img_arr" :key="item">
			<image :src="item" class="image-item" :style="{ width: width, height: height }" @click="openPic(item)"></image>
			<image src="../../static/classify/shanchu.png" @click="deleteImg(index)" class="deleteIcon"></image>
		</view>
		<view class="add-img-wrap image-item" :style="{ width: width, height: height }" @click="chooseImg" v-if="length > img_arr.length">
			<image src="../../static/detail/phone.png"></image>
		</view>
	</view>
</template>

2.js代码

<script>
import { getToken,getScene } from '@/utils/token';
import { getBaseUrl } from '@/request/request.js';
import { errMsg, logout } from '@/utils/app';
export default {
	props: {
		value: {
			type: [Array]
		},
		// 可以上传的图片数量
		length: {
			type: [Number, String],
			default: 1
		},
		// 需要返回的数据类型
		type: {
			type: String,
			defalut: 'String'
		},
		width: {
			type: String,
			defalut: '140rpx'
		},
		height: {
			type: String,
			defalut: '140rpx'
		}
	},
	data() {
		return {
			baseURL: getBaseUrl(),
			img_arr: []
		};
	},

	watch: {
		img_arr(val) {
			if (this.type == 'String') {
				this.$emit('input', JSON.stringify(val));
			} else {
				this.$emit('input', val);
			}
		},
		value: {
			deep: true,
			immediate: true,
			handler(val) {
				console.log('val', val);
				this.img_arr = val || [];
			}
		}
	},

	methods: {
		chooseImg() {
			const _this = this;
			uni.chooseImage({
				count: _this.length - _this.img_arr.length, //默认9
				sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
				sourceType: ['album'], //从相册选择
				success: function(res) {
					console.log(res);
					_this.addImg(res.tempFilePaths);
				}
			});
		},
		// 添加图片
		addImg(imgList) {
			const _this = this;
			imgList.forEach(item => {
				_this.uploadImg(item).then(res => {
					_this.img_arr.push(res.data);
				});
			});
		},
		// 上传图片
		uploadImg(file) {
			const _this = this;
			uni.showLoading({
				title: '加载中'
			});
			return new Promise((resolve, reject) => {
				uni.uploadFile({
					url: this.baseURL + 'v1/user/upload/image',
					filePath: file,
					name: 'file_image',
					header: {
						token: getToken()
					},
					success: res => {
						console.log('上传',res)
						var scene = getScene();
						if (scene == 'baidu') {
						   let { code, msg } = res.data;
						   resolve(res.data);
						} else {
							let { code, msg } = JSON.parse(res.data);
							resolve(JSON.parse(res.data));
						}
					},
					fail(err) {
						console.log('失败');
						reject(err);
					},
					complete() {
						uni.hideLoading();
					}
				});
			});
		},
		// 图片删除
		deleteImg(index) {
			let _this = this;
			this.$confirm({
				content: '确定删除图片嘛?',
				confirmFunc: () => {
					_this.img_arr.splice(index, 1);
				}
			});
		},
		openPic(item) {
			uni.previewImage({
				current: item,
				urls: this.img_arr
			});
		}
	}
};
</script>

3.css代码

<style lang="scss">
.uploadImgPage {
	display: flex;
	flex-wrap: wrap;

	.image-item {
		margin-left: 26rpx;
		margin-bottom: 30rpx;
	}

	.add-img-wrap {
		display: flex;
		align-items: center;
		justify-content: center;
		border: 1px dashed #999;
		image {
			object-fit: cover;
			height: 56rpx;
			width: 70rpx;
		}
	}

	.img-wrap {
		position: relative;
		.deleteIcon {
			width: 32rpx;
			height: 32rpx;
			position: absolute;
			top: -10rpx;
			right: -12rpx;
			z-index: 999;
		}
	}

	:nth-child(3n) {
		margin-right: 0;
	}
}
</style>

4.在main.js 全局引用

import UploadImg from "@/components/upload-img/upload-img.vue"
Vue.component('upload-img', UploadImg)

5.页面引用

<upload-img :length="4" width="140rpx" height="140rpx" v-model="image_arr"></upload-img>

export default {
   data() {
		return { 
                       image_arr: []
                }
                
          }

}