uniapp 基于uni-file-picke实现上传

一、需要

     之前有个实名认证的界面,需要上传身份认证的消息,手动上传,点击提交按钮的时候,先上传图片,等所有图片上传成功后在调用提交的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 }];
       }
     }

el-time-picker 是 Element UI 框架中的一个时间选择器组件,而 is-range 则是指该时间选择器作为范围选择器使用的一种模式。 基本使用 el-time-picker 组件时,你需要在 Vue 组件中引入该组件,并在模板中使用它。下面是一个基本的示例: ```vue <template> <div> <el-time-picker v-model="time" placeholder="选择时间" ></el-time-picker> </div> </template> <script> export default { data() { return { time: '' }; } }; </script> ``` 在上面的示例中,我们创建了一个 el-time-picker 组件,并使用 v-model 指令将选中的时间绑定到 data 中的 time 变量上。通过设置 placeholder 属性,我们可以为时间选择器设置一个占位符。 如果你想使用 el-time-picker 作为范围选择器,可以通过设置 is-range 属性来实现。下面是一个示例: ```vue <template> <div> <el-time-picker v-model="timeRange" is-range range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" ></el-time-picker> </div> </template> <script> export default { data() { return { timeRange: [] }; } }; </script> ``` 在上面的示例中,我们设置了 is-range 属性来指定 el-time-picker 为范围选择器。通过设置 range-separator 属性,我们可以定义时间范围的分隔符。同时,我们还设置了 start-placeholder 和 end-placeholder 属性来分别为开始时间和结束时间设置占位符。 这样,你就可以基本使用 el-time-picker 和 is-range 来实现时间选择和时间范围选择的功能了。希望对你有帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值