朋友们,按照上文(方式一)思路,实现了动态表格和表头分组,这篇按照方式一的需求,扩展出另一种代码写法;
一、表格头
表格columns 还是定义在data() {} 中,初始化静态列数组,配置项列由后端接口返回(第二点写动态配置项代码);
在方式一基础上加了 筛选菜单 功能,因此变化代码部分如下:
:columns="filterColumns()"
<a-table ref="table" bordered :columns="filterColumns()" :dataSource="tableData" :loading="loading" :pagination="false" :scroll="{y: tableHeight-60, x:'max-content'}" :style="{ height: tableHeight+ 'px' }"></a-table>
// data定义 columns静态列
columns: [ { title: '单号', dataIndex: 'businessNumber', key: 'businessNumber', width: 200, },{ title: '时间', dataIndex: 'adTimeText', key: 'adTimeText', width: 160, },{ title: '单据类型', dataIndex: 'adTypeText', key: 'adTypeText', width: 120, },{ title: '类型', dataIndex: 'type', key: 'type', width: 120, customRender: (text)=>{ return <span>{text==1?'分明细':'平明细'}</span> } },{ title: '状态', dataIndex: 'adStatus', key: 'adStatus', width: 120, scopedSlots: { filterDropdown: 'ADStatusFilter',customRender: 'ADStatusSlot' }, },{ title: '总额', dataIndex: 'total', key: 'total', width: 90, }, ],
表头增加筛选菜单功能,因为data() 定义中尽量不用this,所以添加筛选菜单时,放在methods方法上,如下:
// 表头筛选菜单
filterColumns(){ const columns = deepClone(this.columns) columns.map(item => { if(item.key == 'adStatus'){ this.$set(item, 'filtered', this.adStatus); // 标识数据是否经过过滤,图标会高亮 } return item }) return columns },
表格状态列加了筛选功能,筛选图标是否高亮由 this.adStatus 值变化,绑定adStatus状态如下:
<template slot="ADStatusFilter" slot-scope="{ confirm }"> <SelectSearch v-model="adStatus" :options="adStatusList" @search="val=>{ handleSearch(val,confirm)}"></SelectSearch> </template>
二、表格体
展现内容和上文一样,和方式一的区别在于企微主体名称所在的列需要动态计算宽度,不然渲染就会列错位,解决方式如下:
关键代码是 getTextWidthFn()
async queryList(){ let res = await GetList() let {data}=res.data let result =data&&data.length?data.sort((a1,a2)=>a1.sort-a2.sort):[] let colArr=[] // 获取企微主体名称文字的宽度 const getTextWidthFn = (text)=>{ const fontfamily = "Microsoft YaHei,PingFang SC" const canvas = document.createElement("canvas") const ctx = canvas.getContext("2d") ctx.font = `14px ${fontfamily}` const textMetrics = ctx.measureText(text) const actual = Math.abs(textMetrics.actualBoundingBoxLeft) + Math.abs(textMetrics.actualBoundingBoxRight)+32 // 加表头滚动条边距32 return Math.ceil(Math.max(textMetrics.width, actual)) } result.forEach((el,index)=>{ let i=index+1 let textWidth = getTextWidthFn(el.subjectName) textWidth = textWidth&&textWidth<132?'132px': textWidth+'px' // 如果计算出文字宽度小于132,固定宽度为132px colArr.push({ title: el.subjectName, dataIndex: 'alreadyTotal'+i, // 企微主体名称列索引值 key: 'alreadyTotal'+i, // 注意i值 scopedSlots: { customRender: 'alreadyTotalSlot' }, width: textWidth, customCell: () => { return { style: { width: textWidth } } }, id: el.subjectId, }) }) if(JSON.stringify(this.accountData)!=JSON.stringify(colArr))this.columns=this.columns.concat(colArr) this.accountData=colArr this.$nextTick(()=>{ this.queryPage() }) },
代码思路是: 通过canvas设置文字大小和内容,通过 ctx.measureText 计算出文字宽度,赋值给列宽,然后设置单元格属性;
列数组计算完后,合并静态列和动态列数组,渲染到表格上。
表格列动态绘制及列宽展示代码,结束啦,哈哈哈~
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步