uniapp3.0实现图片上传公用组件上传uni-file-picker,uni.uploadFile

用uniapp3.0的写法组合式api,setup形式封装一个图片上传公用组件,要求

1、使用uni-file-picker选择文件

2、uni.uploadFile上传图片

3、要能支持上传接口动态化

4、支持删除如片列表中已上传项

5、可以预览已上传列表图片

6、支持动态化限制图片格式,图片大小,

7、上传成功后走公用组件返回图片列表list,

具体的封装代码,和在页面使用该组件的例子

组件ImageUploader.vue

复制代码
<template>
  <view class="image-uploader">
    <view class="header">
      <text>图片上传</text>
      <text>{{ uploadedFiles.length }}/{{ maxCount }}</text>
    </view>
    <uni-file-picker multiple :limit="maxCount" :disable="uploadedFiles.length >= maxCount" @select="onFileChange"
      :ext-class="filePickerClass" :file-extname="allowedFormats" @delete="removeImage">
      <view class="upload-btn">
        <uni-icons type="camera-filled" color="#007aff" size="40"></uni-icons>
      </view>
    </uni-file-picker>
  </view>
</template>

<script setup>
  let base = import.meta.env.VITE_APP_BASE_API
  let token = uni.getStorageSync(ACCESS_TOKEN)
  const props = defineProps({
    maxCount: {
      type: Number,
      default: 1
    },
    uploadUrl: {
      type: String,
      default: '/ap/files/upload555'//自己的上传地址
    },
    allowedFormats: {
      type: Array,
      default: () => ['jpg', 'jpeg', 'png', 'gif']
    },
    maxSize: {
      type: Number,
      default: 5 * 1024 * 1024 // 5MB
    },
    value: {
      type: Array,
      default: () => {
        return [];
      },
    },
  })
  const emit = defineEmits(['update:list'])

  const uploadedFiles = computed({
    get: () => {
      return props.value;
    },
    set: (val) => {
      emit('update:value', val);
    },
  });
  const onFileChange = async (files) => {
    console.log('files', files)
    // const files = event.detail.tempFiles
    const filelist = files.tempFiles; // 获取选中的文件


    for (const file of filelist) {
      if (!props.allowedFormats.includes(file.name.split('.').pop().toLowerCase())) {
        uni.showToast({
          title: '不支持的文件格式',
          icon: 'none'
        })
        continue
      }

      if (file.size > props.maxSize) {
        uni.showToast({
          title: '文件大小超出限制',
          icon: 'none'
        })
        continue
      }
      console.log('hsjhj')
      uni.uploadFile({
        url: base + props.uploadUrl,
        filePath: file.path,
        name: 'file', // 这里根据API的要求来定义
        header: {
          // 'Content-Type': 'multipart/form-data', // 设置上传文件的 Content-Type
          'Authorization': `Bearer ${token}`, // 自定义头部信息,比如 Authorization
          'Tenant-Id': 1,
          'CLIENT-TOC': 'Y'
        },
        success: (uploadFileRes) => {
          console.log('upload success:', uploadFileRes);
          let data = JSON.parse(uploadFileRes.data)
          console.log('upload success: data', data);
          if (data && data.code == 0) {
            uploadedFiles.value.push({
              url: data.data.url
            })
            console.log('uploadedFiles.value', uploadedFiles.value.length);
            emit('update:list', uploadedFiles.value)
          } else {
            tip.error('上传失败')
          }

        },
        fail: (error) => {
          console.error('upload fail:', error);
          tip.error('上传失败')
          // 处理上传失败的逻辑
        }
      });

    }
  }

  const previewImage = (url) => {
    uni.previewImage({
      urls: uploadedFiles.value.map(file => file.url),
      current: url
    })
  }

  const removeImage = (file) => {
    console.log('hhj', file)
    uploadedFiles.value.splice(file.index, 1)
    emit('update:list', uploadedFiles.value)
  }

  const filePickerClass = {
    'file-picker': true,
    'disabled': uploadedFiles.value.length >= props.maxCount
  }
</script>

<style scoped>
  .image-uploader {
    padding: 16px;
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
  }

  .header {
    display: flex;
    justify-content: space-between;
    margin-bottom: 8px;
  }

  .upload-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 80px;
    height: 80px;
    border: 2px dashed #ddd;
    border-radius: 8px;
    color: #bbb;
  }
</style>

页面使用,预留了上传成功后的回调方法,可不传,也可以直接v-model绑定

复制代码
      <imageUploader :max-count="4" @update:list="updateImageList" v-model:value="imageList"/>
 const imageList = ref([])
 const updateImageList = (list) => {
    console.log('imageList444',imageList)
    // imageList.value = list ,//可以赋值也可以做其他操作
  }
相关推荐
EndingCoder1 分钟前
函数基础:参数和返回类型
linux·前端·ubuntu·typescript
码客前端7 分钟前
理解 Flex 布局中的 flex:1 与 min-width: 0 问题
前端·css·css3
Komorebi゛7 分钟前
【CSS】圆锥渐变流光效果边框样式实现
前端·css
工藤学编程20 分钟前
零基础学AI大模型之CoT思维链和ReAct推理行动
前端·人工智能·react.js
徐同保20 分钟前
上传文件,在前端用 pdf.js 提取 上传的pdf文件中的图片
前端·javascript·pdf
怕浪猫21 分钟前
React从入门到出门第四章 组件通讯与全局状态管理
前端·javascript·react.js
博主花神22 分钟前
【React】扩展知识点
javascript·react.js·ecmascript
欧阳天风29 分钟前
用setTimeout代替setInterval
开发语言·前端·javascript
EndingCoder33 分钟前
箭头函数和 this 绑定
linux·前端·javascript·typescript
郑州光合科技余经理33 分钟前
架构解析:同城本地生活服务o2o平台海外版
大数据·开发语言·前端·人工智能·架构·php·生活