一、需要
之前有个实名认证的界面,需要上传身份认证的消息,手动上传,点击提交按钮的时候,先上传图片,等所有图片上传成功后在调用提交的api 进行确认,
类似界面:
封装一个上传的组件
UploadItem.vue
<template>
<!-- 文件选择器组件,支持图片选择、删除,并绑定本地数据模型 -->
<uni-file-picker @select="handleFileSelect" @delete="handleFileDelete" v-model="localUploadModel"
file-mediatype="image" mode="grid" :image-styles="imageStyles" :limit="1" :auto-upload="false">
<!-- 如果没有选择文件,显示默认图片 -->
<image v-if="!localUploadModel.length" :src="getDefaultImageSrc" mode="scaleToFill" />
<!-- 如果选择了文件,遍历显示每个文件的缩略图 -->
<view v-else v-for="(file, index) in localUploadModel" :key="index">
<image :src="file.url"></image>
</view>
</uni-file-picker>
</template>
<script>
export default {
name: 'uploadItem',
props: {
// 上传文件的数据模型,类型为数组,必填
uploadModel: {
type: Array,
required: true,
},
// 标识符,用于区分不同的上传组件,类型为字符串,必填
identifier: {
type: String,
required: true,
},
// 图片样式配置,类型为对象,默认为空对象
imageStyles: {
type: Object,
default: () => ({}),
},
},
data() {
return {
// 本地数据模型,用于绑定文件选择器的值
localUploadModel: this.uploadModel,
};
},
computed: {
/**
* 根据标识符获取默认图片的路径
* @returns {string} 默认图片的路径
*/
getDefaultImageSrc() {
switch (this.identifier) {
case 'uploadA':
return '../../static/images/ssssss.png';
case 'uploadB':
return '../../static/images/ssssss.png';
default:
return '../../static/images/ssssss.png'; // 默认图片
}
},
},
watch: {
// 监听外部传入的uploadModel变化,同步到本地数据模型
uploadModel(newVal) {
this.localUploadModel = newVal;
},
},
methods: {
/**
* 处理文件选择事件
* @param {Event} event - 文件选择事件对象
*/
handleFileSelect(event) {
this.$emit('file-select', event, this.localUploadModel, this.identifier);
},
/**
* 处理文件删除事件
*/
handleFileDelete() {
this.$emit('file-delete', this.localUploadModel, this.identifier);
},
},
};
</script>
<style scoped>
/* 图片样式,设置宽度和高度 */
image {
width: 156px;
height: 96px;
}
/* 深度选择器,用于覆盖文件选择器组件的默认样式 */
::v-deep .file-picker__box-content {
margin: 0 !important;
}
::v-deep .uni-file-picker__container {
margin: 0 !important;
}
::v-deep .file-picker__box {
height: 96px !important;
}
</style>
父组件使用:
<UploadItem :uploadModel="uploadA" identifier="uploadA" :imageStyles="imageStyles"
@file-select="handleFileSelect" @file-delete="handleFileDelete" />
<UploadItem :uploadModel="uploadB" identifier="uploadB" :imageStyles="imageStyles"
@file-select="handleFileSelect" @file-delete="handleFileDelete" />
<button @click="submit">确定</button>
data中定义数据
uploadA: [],
uploadB: [],
imageStyles: {
width: '156px',
height: '92px',
"border": false
},
form: {
front: '',//证件正面图片地址
back: '',//证件反面图片地址
},
methods方法:
// 处理文件选择事件
handleFileSelect(event, localUploadModel, identifier) {
this[identifier] = event.tempFiles;
},
// 处理文件删除事件
handleFileDelete(localUploadModel, identifier) {
this[identifier] = [];
},
// uniapp文件上传
uploadFilePromise(event) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url:你的上传接口地址,
filePath: event.url,
name: "file",
header: {
//请求头信息
},
success: (res) => {
let data = JSON.parse(res.data); // 最终传给的是字符串,这里需要转换格式
if (data.statusCode != 200) {
this.$modal.showToast(data.msg);
}
resolve(data.data.file.full_url);
},
fail: (e) => {
reject();
}
});
});
},
//上传按钮
sumbit(){
// 可以处理表单验证的一下逻辑
//
const uploads = [
{ variable: this.uploadA, name: "uploadA" },
{ variable: this.uploadB, name: "uploadB" },
];
const form = {
...this.form,
urls: {}
};
const promises = uploads.map(async (uploadInfo) => {
try {
const res = await this.uploadFilePromise(uploadInfo.variable[0]);
form.urls[uploadInfo.name] = res;
} catch (err) {
uni.showToast({
title: `${uploadInfo.name} 的图片上传失败,请稍后重试`,
icon: "none",
duration: 2000
});
}
});
//等待所有的图片上传成功
Promise.all(promises)
.then(() => {
let paras = {
...form,
front: form.urls.uploadA,
back: form.urls.uploadB
}
// 所有图片上传成功后在这里调用提交的api
//比如this.postSumbit(paras);
})
.catch((error) => {
console.error("处理上传时发生错误:", error);
}).finally(() => {
this.loading = false;
});
},
//提交api
async postSumbit(form) {
const res = await 你的api(form);
if (res.code == 1) {
this.$modal.msgSuccess('提交成功')
// this.$modal.closeLoading()
} else {
this.$modal.msgError(res.msg)
// this.$modal.closeLoading()
}
},
//如果需要回显数据的话
async getInfo() {
const res = await 回显Api();
if (res.code == 1) {
this.form = res.data;
this.uploadA = [{ url: res.data.front_image }];
this.uploadB = [{ url: res.data.back_image }];
}
}