vben admin BasicTable 表格的进阶使用之带搜索区域
前言
很久之前看了下关于 vben 的基础使用,最近项目需求开始用了,业务需要一个带搜索区域的表格,今天写完有点懵逼,来记录的过程中整理下思路~~
这里是之前写过的关于 vben admin BasicTable 表格的基本使用
一、上代码
<template><BasicTable@register="registerTable"><template#toolbar><a-buttontype="primary"@click="exportData"> 数据导出 </a-button></template></BasicTable></template>
<script lang="ts" setup>import{ BasicForm, FormSchema }from'/@/components/Form';import{ BasicTable, useTable }from'/@/components/Table';import{ getBasicColumns }from'./details/tableData';import{ reactive, ref, unref, watch, nextTick }from'vue';import{ getTowersInfo, towerLatestData }from'/@/api/bu/device/device';import{ towerBillPage, exportTowerHistoryToExcel }from'/@/api/bu/device/towerBill';//这里是表格中搜索区域表单的配置,就和 FORM 的配置是一样的constdetailSearchForm: FormProps ={baseColProps:{lg:6,md:8},labelWidth:90,schemas:[{label:'工作类型',field:'workType',component:'Select',componentProps:{dictType:'tower_bill_type',},},{label:'单据时间',field:'startTime',component:'RangePicker',componentProps:{format:'YYYY-MM-DD HH:mm:ss',},},],};const[registerTable,{ reload, getForm }]=useTable({api: towerBillPage,beforeFetch:(params)=>{
params.deviceId = deviceId;return params;},afterFetch:(result)=>{// handleTowerHistory是自己写的关于拿到返回数据后进行的一些处理的函数returnhandleTowerHistory(result);},columns:getBasicColumns(),showIndexColumn:false,useSearchForm:true,formConfig: detailSearchForm,showTableSetting:true,tableSetting:{// 是否显示刷新按钮redo:true,size:false,// 是否显示字段调整按钮setting:false,// 是否显示全屏按钮fullScreen:false,},canResize:true,});// 使用在表格插槽中放了一个按钮,对应的点击事件,是用来下载文件的functionexportData(){// getForm().resetFields()let data =getForm().getFieldsValue();exportTowerHistoryToExcel({ deviceId,createTime: data.startTime }).then((url)=>{let fileName = url.slice(url.lastIndexOf('/')+1);fetch(url).then((res)=> res.blob()).then((blob)=>{const link = document.createElement('a');
link.href =URL.createObjectURL(blob);// 下载文件的名称及文件类型后缀
link.download = fileName;
document.body.appendChild(link);
link.click();//在资源下载完成后 清除 占用的缓存资源
window.URL.revokeObjectURL(link.href);
document.body.removeChild(link);});});}</script >
二、上最终效果
三、代码分析
1.创建实例
我这里使用 useTable 的方式
如果需要开启搜索区域,在 useTable 的配置过程中需要加上下面的配置项
useSearchForm boolean false 使用搜索表单
formConfig any 表单配置,参考表单组件的 Props
2. 表格设置工具的配置
默认表格的设置区域的样式是这样子的,但是实际上并不需要这些,只保留一个刷新就可以了
配置项
showTableSetting boolean false- 显示表格设置工具
tableSetting TableSetting -- 表格设置工具配置,见下方 TableSetting
2.使用 table 的插槽来放置按钮
这里使用了 basic table 的插槽来实现的
<BasicTable@register="registerTable"><template#toolbar><a-buttontype="primary"@click="exportData"> 数据导出 </a-button></template></BasicTable>
3.获取搜索区域表单的值
业务需求,在点击
数据导出
按钮的时候,执行 exportData() 函数需要发请求获取对应的文件 url 地址来实现下载功能
但是这个请求是需要带表格搜索区域的时间条件作为参数的,所以我需要获取到搜索表单中的数据
在官方文档中可以看到,table 的 methods 中是有 getForm() 的
在 exportData() 方法中,调用 getForm() 方法,获取到搜索表单实例对象
再调用 form 实例对象的getFieldsValue() 来获取数据
let data =getForm().getFieldsValue();
functionexportData(){// getForm().resetFields()let data =getForm().getFieldsValue();exportTowerHistoryToExcel({ deviceId,createTime: data.startTime }).then((url)=>{let fileName = url.slice(url.lastIndexOf('/')+1);fetch(url).then((res)=> res.blob()).then((blob)=>{const link = document.createElement('a');
link.href =URL.createObjectURL(blob);// 下载文件的名称及文件类型后缀
link.download = fileName;
document.body.appendChild(link);
link.click();//在资源下载完成后 清除 占用的缓存资源
window.URL.revokeObjectURL(link.href);
document.body.removeChild(link);});});}
4.实现在外部调用表单的 reload()
业务表单需要在某些时机来刷新,而不是手动点击表单设置工具区域的刷新按钮,所以就需要表格实例对象的 reload() 方法
const[registerTableA,{ reload, getForm }]=useTable({.....});reload();
这样在需要刷新表单的时候执行 reload 就可以了
遗留思考 (已解决)
如果一个页面当中有多个表单实例的话 , emmm 分别需要在两个位置执行这两个表单的 reload()
如果出现下面的情况,怎样区分 是哪个表单的 relaod 呢?
(盲猜测以下代码会报错 毕竟出现了两个 reload 两个 getForm )
const[registerTableA,{ reload, getForm }]=useTable({.....});const[registerTableB,{ reload, getForm }]=useTable({.....});
(继续猜测,没时间验证,等真的遇到可以试试看? 主要还是对 vue3 了解太差了) (验证过了,失败)
const[registerTableA,{ reload as reloadA, getForm as getFormA }]=useTable({.....});const[registerTableB,{ reload as reloadB, getForm as getFormB }]=useTable({.....});reloadA();reloadB();
猜测失败
//直接编译失败了const[registerTableA,{ reload as reloadA, getForm as getFormA }]=useTable({.....});const[registerTableB,{ reload as reloadB, getForm as getFormB }]=useTable({.....});reloadA();reloadB();
// reloadA is not definedconst[registerTableA,{reloadA:reload, getForm}]=useTable({.....});const[registerTableB,{reloadB:reload, getForm}]=useTable({.....});reloadA();reloadB();
解决方案
这里主要还是 ES6 解构赋值的基本功了, 在 结构赋值中变量命名冲突的问题,可以通过使用别名的方式来解决
// reloadA is not definedconst[registerTableA,{reload:reloadA, getForm}]=useTable({.....});const[registerTableB,{reload:reloadB, getForm}]=useTable({.....});reloadA();reloadB();
总结
之前一直以为需要先通过给 table 或者 form 绑定 ref ,才能执行到 reload() , getFieldsValues() … 方法,但是实际上这种方式获取的好像是 DOM 对象,而不是实例对象
所以在 useTable 的时候将 reload 写进去页面中就会有 reload() 方法可以直接调用了
版权归原作者 YZRHANYU 所有, 如有侵权,请联系我们删除。