实例简介
本例分享图片上传组件的实现过程,并实现下面可配置的参数:
1、maxLength图片最大上传数量;
2、maxSize单文件大小限制;
3、allowTypes文件类型限制;
并实现图片预览和图片删除方法等。
功能实现
1、组件搜索(uni-img-upload)实现代码
01 template代码
<template>
<view class="group-images">
<view class="image-box" v-for="(item, index) in images" :key="item.id">
<image class="upload-imgs" :class="item.loaded?'show':''" :src="item.url" mode="aspectFill" :data-id="item.id" :data-index="index"
@click="imagePreview" @load="endLoading" @error="endLoading">
</image>
<button class="img-loading" loading v-if="!item.loaded"></button>
<text class="del-t" :data-index="index" @click="delImage">删除图片</text>
</view>
<view class="addImage" @click="chooseGroupImage" v-if="images.length < maxLength"></view>
</view>
</template>
02 script代码
<script>
export default {
name: "uni-img-upload",
props: {
// 最大上传数量
maxLength: {
type: Number,
default: 1
},
// 单文件大小限制,默认 1M
maxSize: {
type: Number,
default: 1024
},
// 文件类型限制
allowTypes: {
type: String,
default: 'JPG,JPEG,PNG,BMP'
}
},
data() {
return {
images: []
}
},
methods: {
// 选择图片
chooseGroupImage: function(event) {
let that = this;
let imgs = this.images;
if (imgs.length >= this.maxLength) return;
let max = this.maxLength - this.images.length;
uni.chooseImage({
count: max,
sizeType: ['compressed'], // 压缩图
sourceType: ['album', 'camera'], // 相册 / 相机
success(res) {
if (!that.checkImgType(res.tempFiles)) return;
if (!that.checkImgSize(res.tempFiles)) return;
// 开始上传图片,uploadImgs 中会结束 loading
uni.showLoading({
title: '上传图片中...',
mask: true
});
that.uploadImgs(res.tempFiles);
}
});
},
// 上传图片(如果是调用接口,可在此修改)
uploadImgs: function(imgs, index = 0) {
let images = this.images;
imgs.map((item, index) => {
images.push({
id: index,
url: item.path
});
});
this.images = images;
uni.hideLoading();
},
// 检查图片类型
checkImgType: function(imgs) {
const allowTypes = this.allowTypes.toUpperCase();
for (let i = 0; i < imgs.length; i++) {
let item = imgs[i];
let type = item.name.slice(item.name.lastIndexOf('.') + 1);
type = type ? type.toUpperCase() : ',,';
if (allowTypes.indexOf(type) < 0) {
uni.showToast({
title: '请上传 ' + this.allowTypes + ' 格式图片',
icon: 'none',
duration: 2000
});
return false;
}
}
return true;
},
// 检查图片大小
checkImgSize: function(imgs) {
for (let i = 0; i < imgs.length; i++) {
let item = imgs[i];
if (item.size / 1024 > this.maxSize) {
let info = '';
if (this.maxSize > 1024) info = (Math.floor(this.maxSize / 1024 * 100) / 100) + 'M';
else info = this.maxSize + 'KB';
uni.showToast({
title: '图片大小超出限制(' + info + ')',
icon: 'none',
duration: 2000
});
return false;
}
}
return true;
},
// 删除图片
delImage: function(event) {
let index = event.currentTarget.dataset.index;
let images = this.images;
images.splice(index, 1); // 删掉点击的图片
this.images = images;
},
// 图片预览
imagePreview: function(event) {
if (this.disabled) return;
let index = event.currentTarget.dataset.index;
let images = this.images;
let imgUrls = [];
images.map(item => imgUrls.push(item.url));
uni.previewImage({
current: imgUrls[index], // 当前显示图片的http链接
urls: imgUrls // 需要预览的图片http链接列表
});
},
// 图片加载结束事件
endLoading: function(event) {
let ii = event.currentTarget.dataset.index;
let id = event.currentTarget.dataset.id;
// 删除操作后仍然会触发此事件,使用 id 做对比
if (!this.images[ii] || this.images[ii].id !== id) return;
this.$set(this.images[ii], 'loaded', true);
}
}
}
</script>
03 style代码
<style lang="less" scoped>
.group-images {
margin: 0 50rpx;
.image-box {
display: inline-block;
width: 140rpx;
height: 140rpx;
position: relative;
margin-right: 30rpx;
margin-bottom: 20rpx;
&:nth-child(4n) {
margin-right: 0;
}
.upload-imgs {
width: 140rpx;
height: 140rpx;
border-radius: 8rpx;
opacity: 0;
transition: opacity 1s;
&.show{
opacity: 1;
}
}
.img-loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 40rpx !important;
height: 40rpx !important;
padding: 0 !important;
line-height: 40rpx !important;
background-color: transparent;
border: none;
&::after{
border: none;
}
}
.del-t {
position: absolute;
bottom: 0;
left: 0;
font-size: 26rpx;
background-color: rgba(204, 204, 204, 0.6);
width: 100%;
text-align: center;
padding: 6rpx 0;
}
}
.addImage {
display: inline-block;
color: #3d7af5;
font-size: 100rpx;
border: 2rpx solid #e5e5e5;
width: 136rpx;
height: 136rpx;
text-align: center;
overflow: hidden;
border-radius: 8rpx;
position: relative;
&::before {
content: '';
display: block;
position: absolute;
background: #ed292a;
width: 50rpx;
height: 6rpx;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 6rpx;
}
&::after {
content: '';
display: block;
position: absolute;
background: #ed292a;
width: 6rpx;
height: 50rpx;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 6rpx;
}
}
}
</style>
2、页面引用组件
Tips:可根据需要自行配置参数
<template>
<view>
<uni-img-upload ref="progressImgs" :max-length="5"></uni-img-upload>
</view>
</template>
<script>
import uniImgUpload from '../../components/uni-img-upload/uni-img-upload';
export default {
data() {
return {
}
},
onLoad() {
},
methods: {
}
}
</script>
<style lang="less" scoped>
</style>