vue3点击按钮下载文件功能的代码实现
作者:栀椩
在写vue项目时,有个需求是点击表格中某一行的下载按钮,然后开始下载这一行对应的文件,所以本文小编给大家介绍了使用vue3实现点击按钮下载文件功能,文中有详细的代码示例供大家参考,需要的朋友可以参考下
VUE3实现点击按钮下载文件功能
在写vue项目时,有个需求是点击表格中某一行的下载按钮,然后开始下载这一行对应的文件,效果如下:
表格每行的最右侧的蓝色按钮就是点击下载,这里涉及到原生的JavaScript写法,长期在写vue项目,原生的写法都很陌生了,记录一下
先上组件的原始代码:
<template> <BreadCrumb ref="breadCrumb" :item="item"></BreadCrumb> <div class="pane-content"> <div class="pane-top"> <div class="module-common-header"> <div class="button-wrapped"> <el-upload v-model:file-list="fileList" class="upload-demo" multiple :on-exceed="handleExceed" action="http://127.0.0.1:3088/api/files/uploadFile" :on-success="handleSuccess" :show-file-list="false"> <el-button type="primary">上传文件</el-button> </el-upload> </div> </div> <div class="module-common-table"> <el-table :data="tableData" border style="width: 100%"> <el-table-column type="index" width="50"></el-table-column> <el-table-column show-overflow-tooltip v-for="(item, index) in tableLabel" :key="index" :prop="item.prop" :label="item.label" /> <el-table-column fixed="right" label="操作"> <template #default="scope"> <el-button type="primary" size="small" @click="downloadFile(scope.row)">下载文件</el-button> <el-popconfirm title="确定删除该文件吗?" confirm-button-text="是" cancel-button-text="否" @confirm="deleteFile(scope.row)"> <template #reference> <el-button type="danger" size="small">删除文件</el-button> </template> </el-popconfirm> </template> </el-table-column> </el-table> </div> </div> <div class="table-footer"> <el-pagination :page-size="10" :pager-count="5" layout="prev, pager, next" :total="filesLength" :current-page="paginationData.currentPage" @current-change="currentPageChange" /> </div> </div> </template> <script setup> import { ref, onMounted } from 'vue' import { getFilesLengthAPI, returnFileListDataAPI, bindFileAndUserAPI, deleteFileAPI, updateDownloadTimesAPI, } from '@/apis/files' const item = ref({ first: '合同管理', }) const tableData = ref([]) const tableLabel = [ { prop: 'file_name', label: '合同名' }, { prop: 'file_size', label: '合同文件大小' }, { prop: 'upload_person', label: '上传人' }, { prop: 'download_number', label: '下载次数' }, { prop: 'upload_time', label: '上传时间' }, // { prop: 'message_content', label: '消息内容' }, ] const fileList = ref([]) // 上传成功之后的回调函数 const handleSuccess = async (response, uploadFile, uploadFiles) => { if (response.status == 0) { const name = JSON.parse(localStorage.user).userInfo.name const url = response.url const res = await bindFileAndUserAPI({ name, url }) if (res.status == 0) { ElMessage.success('上传成功') getCurrentPageData() getFilesLength() } else ElMessage.error('上传失败') } else { ElMessage.error('上传失败,请检查是否重名') } } // 超出文件个数限制的钩子 const handleExceed = (uploadFile, uploadFiles) => { } // 下载文件 const downloadFile = async (row) => { // console.log(row) const { download_number, id } = row await updateDownloadTimesAPI({ download_number, id }) const url = row.file_url const link = document.createElement('a') link.href = url link.setAttribute('download', '') document.body.appendChild(link) link.click() document.body.removeChild(link) getCurrentPageData() } // 删除文件 const deleteFile = async row => { const res = await deleteFileAPI({ id: row.id }) if (res.status == 0) ElMessage.success('删除成功') else ElMessage.error('删除失败') getCurrentPageData() getFilesLength() } // 分页 const paginationData = ref({ // 总页数 pageCount: 1, // 当前页 currentPage: 1, }) // 获取数据总数 const filesLength = ref(0) const getFilesLength = async () => { const res = await getFilesLengthAPI() filesLength.value = res.filesCount } // 获取首页数据 const getFirstPageList = async () => { const res = await returnFileListDataAPI({ page: 1 - 1 }) res.forEach(item => { item.upload_time = item.upload_time?.slice(0, 19) item.file_size = Math.floor(item.file_size) + 'kb' }) tableData.value = res } // 页码切换 const currentPageChange = async (val) => { paginationData.value.currentPage = val const res = await returnFileListDataAPI({ page: val - 1 }) res.forEach(item => { item.upload_time = item.upload_time?.slice(0, 19) item.file_size = Math.floor(item.file_size) + 'kb' }) tableData.value = res } // 增删数据后,需要刷新当前页数据 const getCurrentPageData = async () => { const res = await returnFileListDataAPI({ page: paginationData.value.currentPage - 1 }) res.forEach(item => { item.upload_time = item.upload_time?.slice(0, 19) item.file_size = Math.floor(item.file_size) + 'kb' }) tableData.value = res } onMounted(() => { getFilesLength() getFirstPageList() }) </script> <style lang="scss" scoped> .pane-content { margin-top: 8px; display: flex; flex-direction: column; justify-content: space-between; height: calc(100vh - 118px); background: #fff; .pane-top { padding: 8px; background: #fff; .module-common-header { padding: 0 20px; display: flex; align-items: center; justify-content: flex-end; } .module-common-table { min-height: 10px; padding: 10px 20px 20px; margin-bottom: 8px; background: #fff; } } .table-footer { display: flex; justify-content: flex-end; margin-bottom: 8px; } } </style>
我用的是vue3+setup语法糖写法,代码比较长,关注一下与下载相关的代码:
html部分
<el-table-column fixed="right" label="操作"> <template #default="scope"> <el-button type="primary" size="small" @click="downloadFile(scope.row)">下载文件</el-button> <el-popconfirm title="确定删除该文件吗?" confirm-button-text="是" cancel-button-text="否" @confirm="deleteFile(scope.row)"> <template #reference> <el-button type="danger" size="small">删除文件</el-button> </template> </el-popconfirm> </template> </el-table-column>
其实就是表格最后一列,添加两个按钮,然后为这个按钮传入本行的所有数据,下载文件按钮添加点击函数downloadFile,并传入行数据作为参数
JavaScript部分
js部分是实现点击下载的核心,看downloadFile方法
// 下载文件 const downloadFile = async (row) => { // console.log(row) const { download_number, id } = row // 从行中获取下载文件接口的传入参数 await updateDownloadTimesAPI({ download_number, id }) // 调用下载文件的接口 const url = row.file_url // 从行数据中获取下载链接 const link = document.createElement('a') // 创建链接标签,即a标签,并将dom命名为link link.href = url // 为dom为link的元素添加链接 link.setAttribute('download', '') // 为link设置下载属性 document.body.appendChild(link) // 把创建并配置好的link dom添加到页面文档中 link.click() // 模拟dom的点击事件 document.body.removeChild(link) // 从文档中移出link节点 getCurrentPageData() // 调用写好的方法刷新数据 }
相关的解释我都写在了上面的代码中,其中下面两个步骤不是必须的:
- await updateDownloadTimesAPI({ download_number, id }) ,点击下载后,要在数据库中标记,增加点击量
- getCurrentPageData(),因为操作了数据库,数据要更新,所以这是为了更新数据
以上就是vue3实现点击按钮下载文件功能的详细内容,更多关于vue3下载文件功能的资料请关注脚本之家其它相关文章!