在前端开发中,我们时常需要处理文件上传和下载的功能。有时,用户可能希望将多个文件打包成一个zip文件以便于下载。今天,我将分享一个使用Vue3和JSZip库在浏览器端实现zip文件压缩的示例。
首先,我们需要安装JSZip库。如果你使用的是npm,可以通过以下命令进行安装:
npm install jszip
在Vue3组件中,我们可以定义一个响应式引用fileDatas
来存储用户上传的文件信息。同时,我们还需要几个其他的引用来控制压缩选项和进度。
<script lang="ts" setup>
import { ref } from 'vue'
import JSZip from 'jszip'
import { saveAs } from 'file-saver' // 注意这里我假设你已经有file-saver库了
interface FileData {
file: File
fileName: string
}
const fileDatas = ref<FileData[]>([])
const isCompress = ref(false) // 是否启用压缩
const compressionLevel = ref(6) // 压缩级别
const packagingPercentage = ref(0) // 压缩进度
// 文件上传处理函数
const fileUpload = (file: File) => {
fileDatas.value.push({
file,
fileName: file.name
})
}
// 打包为zip文件
const packageAsZip = async () => {
packagingPercentage.value = 0
const zip = new JSZip()
fileDatas.value.forEach((fileData) => {
zip.file(fileData.fileName, fileData.file)
packagingPercentage.value += 100 / fileDatas.value.length // 简化进度计算
})
let content: Blob
if (isCompress.value) {
content = await zip.generateAsync({
type: 'blob',
compression: 'DEFLATE',
compressionOptions: { level: compressionLevel.value }
})
} else {
content = await zip.generateAsync({ type: 'blob' })
}
saveAs(content, 'compressed_files.zip')
}
</script>
<template>
<div>
<!-- 假设你有一个文件上传组件CommonFileUploadWithDirectory -->
<CommonFileUploadWithDirectory @upload="fileUpload" />
<!-- 压缩按钮 -->
<button @click="packageAsZip">压缩为ZIP</button>
<!-- 文件列表展示 -->
<div v-if="fileDatas.length > 0" class="file-list">
<div v-for="(fileData, index) in fileDatas" :key="index" class="file-list-item">
<!-- 假设你有一个删除按钮组件,这里用了一个简单的删除逻辑 -->
<button @click="fileDatas.splice(index, 1)">删除</button>
<span>{{ fileData.fileName }}</span>
</div>
</div>
</div>
</template>
<style scoped>
/* 样式省略 */
</style>
在上面的代码中,我们定义了一个文件上传处理函数fileUpload
,每当用户上传一个文件时,就将文件信息添加到fileDatas
数组中。我们还定义了一个packageAsZip
函数,该函数会遍历fileDatas
数组中的每个文件,并使用JSZip将它们添加到zip文件中。然后,根据isCompress
的值决定是否启用压缩,并生成一个Blob对象。最后,使用file-saver
库的saveAs
函数将Blob对象保存为zip文件。
注意,我在计算压缩进度时进行了简化,直接假设每个文件占据相等的进度。在实际应用中,你可能需要根据文件的大小或压缩的实际情况来更精确地计算进度。
实际案例:https://anttoolbox.cn/tools/zip,这里我参与了开发~~~
Zova 是一款支持 IOC 容器的 Vue3 框架。有了 IOC 容器的加持,定义响应式状态不再需要ref/reactive,也不再需要ref.value