vue3中,下载模板并进行上传导入文件 & 父子组件props传函数两种写法-传动态接口
效果
接口返回模板
传参
返回
代码
1、页面文件
index.vue
<template> <div> <el-button type="primary" @click="() => (isShowImport = true)"> 导入 </el-button> <!-- 导入 --> <importPopup v-model:showDialog="isShowImport" :download-fun="downLoadPlanEvent" :import-fun="planImport" @import-success="onLoad" /> <el-pagination background :current-page="page.currentPage" layout="total, sizes, prev, pager, next, jumper" :page-size="page.pageSize" :page-sizes="[10, 20, 30, 40, 50, 100]" :total="page.total" @current-change="hanleCurrentChange" @size-change="handleSizeChange" /> </div> </template> <script setup> import { downloadPlanList, planImport, queryByPagePlanList, } from "@/api/acceptManage/index"; import { downLoadxls } from "@src/utils/util"; import importPopup from "@src/components/importPopup"; const page = reactive({ pageSize: 10, currentPage: 1, total: 0, }); const tableData = ref([]); const isShowImport = ref(false); const downLoadPlanEvent = () => { downloadPlanList({}).then((res) => { downLoadxls(res, "结算清单下载"); }); }; const hanleCurrentChange = (val) => { page.currentPage = val; onLoad(); }; const handleSizeChange = (val) => { page.pageSize = val; onLoad(); }; const onLoad = async () => { const formData = { pageSize: page.pageSize, pageNumber: page.currentPage, ...formInline.value, startDate: prjDate.value ? prjDate.value[0] : "", endDate: prjDate.value ? prjDate.value[1] : "", }; await queryByPagePlanList(formData).then((res) => { const { code, data, message } = res; if (code === "00000") { data.data.forEach((item) => { item.processState === "" ? (item.processState = "无") : item.processState; }); tableData.value = data.data; page.total = Number(data.total); } else { ElMessage.error(message); } }); }; </script>
2、封装组件文件
两种写法——fun1.value()和fun2.value(param).then(res)
src\components\importPopup.vue
<!-- showDialog //弹窗是否显示 downloadFun //下载模板方法 importFun //导入方法 import-success //导入成功点击确定回调方法 --> <template> <div class="item-content"> <el-dialog v-model="showDialog" :close-on-click-modal="true" :destroy-on-close="true" :show-close="true" title="导入" width="35%" @close="handleCancel" > <el-upload ref="uploadRef" action="#" class="upload-demo" drag :file-list="fileList" :http-request="uploadFiles" :limit="1" :multiple="false" :show-file-list="true" > <!-- :on-change="handleChange" :on-remove="handleRemove" --> <i class="el-icon-upload"></i> <div class="el-upload__text"> <em>选择文件</em> 或将文件拖拽至此区域 </div> <div class="el-upload__tip">支持格式:xls、xlsx</div> </el-upload> <el-button type="text" @click="handleDownLoadTemplate"> 下载导入模板 </el-button> <div class="upload-footer"> <el-button type="primary" @click="handleSubmit">确 定</el-button> <el-button plain type="primary" @click="handleCancel">取 消</el-button> </div> </el-dialog> <!-- 导入失败 --> <el-dialog v-model="isShowFail" class="fail-dialog" :close-on-click-modal="true" :destroy-on-close="true" :show-close="true" title="导入失败" width="35%" @close="handleClose" > <h4 class="fail-title"> 导入失败,请求改后重新上传,错误数据{
{ errorListData.length }}条,失败原因如下: </h4> <el-table :data="errorListData"> <el-table-column label="行数" prop="index" /> <el-table-column label="错误原因" prop="msg" /> </el-table> </el-dialog> </div> </template> <script setup> const props = defineProps({ showDialog: { type: Boolean, default: false, }, downloadFun: { default: null, type: Function, }, importFun: { default: null, type: Function, }, }) const { downloadFun, importFun } = toRefs(props) const emit = defineEmits(['update:showDialog', 'import-success']) const showDialog = computed({ get: () => props.showDialog, set: (val) => emit('update:showDialog', val), }) const fileList = ref([]) const errorListData = ref([]) const isShowFail = ref(false) const successListData = ref() //下载导入模板 const handleDownLoadTemplate = () => { downloadFun.value() // 传函数写法一 } //提交 const uploadFiles = (options) => { const formData = new FormData() formData.append('file', options.file) //传函数写法二 importFun .value(formData) .then((res) => { const { data, code } = res if (code === '00000') { successListData.value = data } }) .catch((res) => { const { data, code } = res if (code !== '00000') { const { errorList } = data const errs = errorList.map((item) => { return { index: `第${item.row}行`, msg: item.message, } }) errorListData.value = errs fileList.value = [] isShowFail.value = true } }) } const handleSubmit = () => { if (errorListData.value.length > 0) { isShowFail.value = true } else { isShowFail.value = false ElMessage.success('导入成功') emit('update:showDialog', false) emit('import-success', successListData.value) } } // 导入弹窗取消 const handleCancel = () => { emit('update:showDialog', false) } // 导入失败弹窗关闭 const handleClose = () => { isShowFail.value = false errorListData.value = [] } </script> <style lang="scss" scoped> .fail-dialog { .fail-title { margin: 0px 0 10px; } :deep() { .ym-dialog__body { padding: 10px 20px 20px; } } } .upload-footer { display: flex; justify-content: center; } </style>
3、接口文件
src\app\science\api\acceptManage\index.js
import request from '@src/utils/request' import {
sciencePostUrl } from '@/config' //年度验收计划列表 export const queryByPagePlanList = (data) => {
return request({
url: `${
sciencePostUrl}/checkPlan/getPlanPage`, method: 'post', data, }) } //年度验收计划-结算清单下载 export const downloadPlanList = (data) => {
return request({
url: `${
sciencePostUrl}/checkPlan/exportQuery`, responseType: 'blob', headers: {
'Content-Type': 'application/json', }, method: 'post', data, }) } //年度验收计划导入 export const planImport = (data) => {
return request({
url: `${
sciencePostUrl}/checkPlan/importPlan`, method: 'post', data, }) }
src\app\science\config\index.js
/ * @description 4个子配置,vue/cli配置|通用配置|主题配置|网络配置导出 * config中的部分配置由vue.config.js读取,本质是node,故不可使用window等浏览器对象 */ const cli = require('./cli.config') const prefixApi = require('./prefixApi.config') module.exports = {
...cli, ...prefixApi, }
src\app\science\config\prefixApi.config.js
module.exports = {
planPostUrl: '/srbm-prj-plan-front/member', sciencePostUrl: '/srbm-prj-techprj-front/member', }
4、方法文件-本地返回模板
src\utils\util.js
//文件流导出数据处理 export const downLoadxls = (res, fileName) => {
let name = fileName if (res.headers['content-disposition']) {
const contentDisposition = res.headers['content-disposition'].split('=') name = (contentDisposition && decodeURI(contentDisposition[1])) || '' } const file = new File([res.data], name, res.data) const href = URL.createObjectURL(file) const aTag = document.createElement('a') aTag.download = file.name aTag.target = '_blank' aTag.href = href aTag.click() URL.revokeObjectURL(href) } //本地文件下载 下载的模板文件放在public下的file文件夹中 export const downFile = (fileName) => {
const anchor = document.createElement('a') anchor.href = `${
process.env.BASE_URL}static/file/${
fileName}` anchor.setAttribute('download', fileName) anchor.innerHTML = 'downloading...' anchor.style.display = 'none' document.body.appendChild(anchor) setTimeout(() => {
anchor.click() document.body.removeChild(anchor) setTimeout(() => {
self.URL.revokeObjectURL(anchor.href) }, 250) }, 66) } //本地文件下载-自定义文件名 export const downFileNew = (fileName, name) => {
const anchor = document.createElement('a') anchor.href = `${
process.env.BASE_URL}static/file/${
fileName}` anchor.download = name // anchor.setAttribute('download', name) anchor.innerHTML = 'downloading...' anchor.style.display = 'none' console.log('anchor', anchor) document.body.appendChild(anchor) setTimeout(() => {
anchor.click() document.body.removeChild(anchor) setTimeout(() => {
console.log(123, anchor) self.URL.revokeObjectURL(anchor.href) }, 250) }, 66) }
到此这篇vue3中,下载模板并进行上传导入文件 & 父子组件props传函数两种写法-传动态接口的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qdvuejs/10768.html