Vant-ui上传文件时,如果文件过大先压缩文件再上传

本文介绍了一种在前端实现图片上传前进行压缩的方法,通过使用image-conversion插件,设置文件大小限制,并在before-read事件中处理图片压缩。示例代码展示了如何配置van-uploader组件,限制图片大小不超过50MB,并使用async函数进行文件压缩,确保文件大小不超过5M。

1.先安装image-conversion插件

npm i image-conversion --save

2.设置文件限制大小,max-size以及设置组件api(before-read)


            
<van-uploader
    multiple
    :max-size = 'imgMaxSize'
    :before-read = 'beforeRead'
    accept = '.jpg,.jpeg,.png'
/>

multiple ==> 允许同时上传多张图片
imgMaxSize ==> 50 * 1024 *1024这里限制最大为50M

3.编写beforeRead方法进行文件压缩

import * as imageConversion from 'image-conversion';  //引入方法

async beforeRead(file) {
    //是否是多张上传
    if (Array.isArray(file)) {
        for await (let i of file) {
            new Promise((resolve, reject) => {
                return imageConversion.compressAccurately(i, 5 * 1024).then(res => {
                    //这里5 * 1024是把大于5M的文件压缩到5M
                    //此时返回的数据是Blob数据,如果后台没有处理,还需要转成File数据
                    res = new File([res], i.name);
                    resolve(res);
                })
            })
        }
    } else {
        return new Promise((resolve, reject) => {
            imageConversion.compressAccurately(file, 5 * 1024).then(res =>{
                res = new File([res], file.name);
                resolve(res);
            })
        })
    }
}

<think>嗯,用户想在VueVant中实现多文件上传的功能。首,我需要回忆一下VantUploader组件的用法。记得Vant的文档里提到过,Uploader组件支持多选,需要设置multiple属性,并且用v-model绑定文件数组。对了,max-count属性可以限制最上传数量,用户可能需要这个。 接下来,用户可能需要处理上传的逻辑,比如调用API。所以after-read事件应该在这里用,当文件选择后会触发这个函数。然后,在afterRead方法里,可能需要构造FormData对象,把文件添加进去,用axios发送POST请求。不过要注意,多文件上传候,可能需要遍历文件列表,因为multiple选择的话,参数可能是一个数组。 然后用户提到要控制文件小,这应该在after-read的候检查每个文件小,如果超过限制就提示并跳过。比如在beforeRead这个函数里可以做校验,返回true或false来决定是否继续上传。 还有进度显示,VantUploader组件本身有上传中的状态,可能需要结合axios的onUploadProgress事件来更新进度数据。不过文档里可能需要自定义进度条,或者利用Vant的组件来展示。 另外,用户引用的资料里提到文件压缩,可能需要使用canvas或者第三方库来压缩图片,这部分应该在after-read之后处理,压缩后再上。但用户的问题主要是多文件上传,所以可能需要处理这个基础功能,再考虑压缩。 还有,用户可能想要实显示上传结果,比如成功或失败,所以每个文件上传后需要更新状态,并在界面上用不同的图标或文字提示。可能需要一个数组来存储每个文件上传状态,比如progress、status等字段。 最后,接口返回的数据需要记录下来,可能每个文件对应一个响应数据,所以在上传完成后将结果存入数组,方便展示。 需要检查代码示例是否正确,比如v-model绑定的是files数组,multiple属性是否正确,以及after-read处理多文件的情况,比如参数是数组的话要遍历处理。可能之前的示例代码里是单个文件,需要调整成支持多文件。 总结步骤:引入Uploader组件,配置multiple和max-count,处理after-read事件,校验文件小,构造FormData,使用axios上传,处理进度和结果,展示列表和状态。</think>在VueVant中实现多文件上传功能,可以通过以下步骤实现: ### 一、基础配置 1. **安装Vant组件** ```bash npm install vant ``` 2. **引入Uploader组件** ```vue <template> <van-uploader v-model="fileList" multiple :max-count="5" :before-read="validateFile" :after-read="handleUpload" :max-size="10 * 1024 * 1024" @oversize="onOversize" /> </template> ``` ### 二、核心逻辑实现 ```vue <script setup> import { ref } from 'vue'; import axios from 'axios'; const fileList = ref([]); const uploadResults = ref([]); // 文件校验(类型/小) const validateFile = (file) => { if (!['image/jpeg', 'image/png'].includes(file.type)) { showToast('仅支持JPG/PNG格式'); return false; } return true; }; // 文件上传处理 const handleUpload = async (files) => { if (Array.isArray(files)) { // 多文件处理 await Promise.all(files.map(uploadSingleFile)); } else { // 兼容单文件模式 await uploadSingleFile(files); } }; // 单文件上传函数 const uploadSingleFile = async (file) => { const formData = new FormData(); formData.append('file', file.file); try { const response = await axios.post('/api/upload', formData, { onUploadProgress: progress => { file.status = 'uploading'; file.progress = Math.round((progress.loaded / progress.total) * 100); } }); uploadResults.value.push({ name: file.file.name, url: response.data.url, status: 'success' }); } catch (error) { uploadResults.value.push({ name: file.file.name, status: 'failed' }); } }; // 超尺寸处理 const onOversize = () => { showToast('文件小超过10MB限制'); }; </script> ``` ### 三、扩展功能实现 1. **文件压缩(引用[2]技术)** ```javascript import Compressor from 'compressorjs'; const compressImage = (file) => { return new Promise((resolve) => { new Compressor(file, { quality: 0.6, success(result) { resolve(new File([result], file.name)); } }); }); }; ``` 在`handleUpload`中调用: ```javascript const compressedFile = await compressImage(file.file); formData.append('file', compressedFile); ``` 2. **分块上传(引用[2]方案)** ```javascript const CHUNK_SIZE = 2 * 1024 * 1024; // 2MB分块 const uploadChunk = async (chunk, index) => { const formData = new FormData(); formData.append('chunk', chunk); formData.append('index', index); return axios.post('/api/chunk-upload', formData); }; ``` ### 四、界面展示优化 ```vue <template> <div class="upload-status"> <div v-for="(item, index) in uploadResults" :key="index"> <van-icon :name="item.status === 'success' ? 'success' : 'cross'" :color="item.status === 'success' ? '#07c160' : '#ee0a24'" /> {{ item.name }} - {{ item.status }} <van-progress v-if="item.status === 'uploading'" :percentage="item.progress" /> </div> </div> </template> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值