今天做了一个文件下载IDE功能,所以分享出来一起学习一下
首先呢,我的文件是可以使用迅雷工具进行下载的,既然迅雷能够下载,那就前端vue肯定也能啊
页面展示
上代码
<!--使用的是elementUI-->
<template>
<div class="app-container">
<el-table
:data="tableData"
style="width: 100%"
>
<el-table-column
prop="name"
label="驱动名称"
align="center"
/>
<el-table-column
prop="time"
label="驱动最后更改日期"
align="center"
/>
<el-table-column
prop="address"
label="操作"
align="center"
>
<template slot-scope="scope">
<el-link v-if="!scope.row.schedule" icon="el-icon-download" type="primary" @click="downloadZip(scope.row)">下载</el-link>
<el-progress v-else :text-inside="true" :stroke-width="20" :percentage="scope.row.scheduleNumber" status="success" />
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'DriverDownload',
data() {
return {
tableData: [
{
name: '高拍仪驱动程序',
time: '2021-05-08',
address: 'jckz/driver/高拍仪.zip',
// 文件大小主要用于进度条的显示,无其他用途,
fileLength: '96985509',
// 进度条显示
schedule: false,
scheduleNumber: 0
}, {
name: '卡片打印机驱动程序',
time: '2021-05-08',
address: 'jckz/driver/卡片打印机.zip',
fileLength: '215823958',
// 进度条显示
schedule: false,
scheduleNumber: 0
}, {
name: '用户卡发卡工具',
time: '2021-05-08',
address: 'jckz/driver/用户卡发卡工具.zip',
fileLength: '2705218',
// 进度条显示
schedule: false,
scheduleNumber: 0
}, {
name: '针式打印机驱动程序',
time: '2021-05-08',
address: 'jckz/driver/针式打印机.zip',
fileLength: '2844794',
// 进度条显示
schedule: false,
scheduleNumber: 0
}
]
}
},
methods: {
downloadZip(row) {
// 自己封装的方法
this.$downloadGet('base/freeValidation/minio/view?path=' + row.address, row.name + '.zip', this.schedule, row).then(() => {
this.tableData.forEach((x) => {
if (x.name === row.name) {
x.schedule = false
}
})
})
},
schedule(progressEvent, row) {
// 回调的progressEvent参数里有一个progressEvent.loaded和progressEvent.total两个参数,分别意思为已下载的文件大小和总文件大小
// 因为total一直为0,经研究发现需要后端传给我ContentLength到response里这个值才会有值
// 然而又发现后端使用的是minio这个文件服务器,所以这个文件大小太难获取了,所以我决定不改后端,直接写死了文件大小
this.tableData.forEach((x) => {
if (x.name === row.name) {
x.schedule = true
x.scheduleNumber = Math.round(progressEvent.loaded / row.fileLength * 100)
}
})
}
}
}
</script>
<style scoped>
</style>
downloadGet方法
downloadGet(url, filename, callback, callbackParameter) {
NProgress.start()
return service.get(url, {
// 下载的实时回调,axios里的
onDownloadProgress: (a) => {
if (callback) {
callback(a, callbackParameter)
}
},
// 必须的参数
responseType: 'blob',
// 超时时间
timeout: 120000
}).then((r) => {
// 下面的代码就是拿到字节流后转为文件的方法,想研究的可以自行百度
const content = r.data
const blob = new Blob([content], { type: 'application/zip' })
if ('download' in document.createElement('a')) {
const elink = document.createElement('a')
elink.download = filename
elink.style.display = 'none'
elink.href = URL.createObjectURL(blob)
document.body.appendChild(elink)
elink.click()
URL.revokeObjectURL(elink.href)
document.body.removeChild(elink)
} else {
navigator.msSaveBlob(blob, filename)
}
NProgress.done()
}).catch((r) => {
console.error(r)
NProgress.done()
Message({
message: '下载失败',
type: 'error',
duration: messageDuration
})
})
}
代码中解释了为什么total为0的解决方式,怕有些同志没看代码注释,这里重新写一下:
下载接口的response中没有Content-Length这个字段,后端接口返回一下就好了,里面存放的是文件的大小,如下图所示