Ant Design Vue Table组件合并单元格方式
作者:木蓝茶陌*_*
这篇文章主要介绍了Ant Design Vue Table组件合并单元格方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
Ant Design Vue Table组件合并单元格
项目开发中,有时候需要实现单元格合并的需求,这里记录一下在Ant Design Vue的实现。
<template> <div> <a-table bordered :data-source="dataSource" :columns="columns"></a-table> </div> </template> <script> const dataSource = [ { key: '1', school: '林州一中', grade: '高一', class: '二班', name: '徐强' }, { key: '2', school: '林州一中', grade: '高一', class: '一班', name: '林东'}, { key: '3', school: '林州一中', grade: '高一', class: '二班', name: '李丹'}, { key: '4', school: '林州一中', grade: '高二', class: '二班', name: '刘康'}, { key: '5', school: '实验高中', grade: '高三', class: '二班', name: '杨江'}, { key: '6', school: '实验高中', grade: '高三', class: '一班', name: '陈锋'}, { key: '7', school: '实验高中', grade: '高三', class: '二班', name: '李华'}, { key: '8', school: '实验高中', grade: '高四', class: '二班', name: '赵铭'} ] const columns = [ { title: '学校', dataIndex: 'school', width: '25%', scopedSlots: { customRender: 'school' }, align: 'center', key: 'school', customRender (_, row) { return { children: row.school, attrs: { rowSpan: row.schoolRowSpan } } } }, { title: '年级', dataIndex: 'grade', width: '25%', scopedSlots: { customRender: 'grade' }, align: 'center', key: 'grade', customRender (_, row) { return { children: row.grade, attrs: { rowSpan: row.gradeRowSpan } } } }, { title: '班级', dataIndex: 'class', width: '25%', scopedSlots: { customRender: 'class' }, align: 'center' }, { title: '姓名', dataIndex: 'name', width: '25%', scopedSlots: { customRender: 'name' }, align: 'center' } ] export default { name: 'TableMerge', data () { return { dataSource, columns } }, methods: { // 合并单元格 rowSpan (key, data) { const arr = data .reduce((result, item) => { if (result.indexOf(item[key]) < 0) { result.push(item[key]) } return result }, []) .reduce((result, keys) => { const children = data.filter(item => item[key] === keys) result = result.concat( children.map((item, index) => ({ ...item, [`${key}RowSpan`]: index === 0 ? children.length : 0 })) ) return result }, []) return arr }, // 表格合并 mergeRowCell (data) { let tableData = this.rowSpan('school', data) tableData = this.rowSpan('grade', tableData) this.dataSource = tableData } }, mounted () { this.mergeRowCell(this.dataSource) } } </script>
合并前:
合并第一列:
合并第二列:
Ant-vue table的单元格合并已经使用自己的slot插槽
之前在做一个ant-design的项目的时候,遇到一个单元格合并的问题,简直头疼,其实在ant中进行简单的内容合并单元格,其实很容易也很方便,最简单的凡是就是在a-table-column标签中进行绑定一个function,代码如下(由于之前比较喜欢template的方式,所以下面都是template的方式进行代码展示,js的数据方式逻辑是一样的):
//核心是customRender这个对象 <a-table-column data-index="logisticObj" width="150px" :customRender="mergeTable" /> //js //children是返回的内容,attrs里面是合并的单元格公式,后面的数字是代表几行/列 ,如果被合并了的未知就用0进行占位 mergeTable(text, record, index) { return { children: text, attrs: { rowSpan:1 }, } },
到这里一些简单的合并什么的基本上都能进行处理了。
接下来难点来了,我们经常会在column中进行设置一个自己的插槽,但是貌似这这里设置一个插槽并不会进行渲染,亲测过很多次,返回的都是children中的内容。
针对这个,特意去了解了下源码中的要求,这里只能插入 jsx 语法的代码片段。如果是react开发的人,应该对这个不默认,但是vue中用的 jsx 还是相对较少的,比如返回一个链接:
return { children: <a>text</a>, // 一个div <div>text<div> //一个js处理了的内容 <div>{text.length}</div> //一个html的代码字符串 <span domPropsInnerHTML = { htmlInfoStr }></span> //剩下的html代码等类似 attrs: { rowSpan:1 }, }
通过上面的,简单的类似于slot的使用方式也能进行渲染了,使用真是的slot研究了一段时间,貌似没有研究成功,如果有人有了结果,可以私信@我一下,互相学习一下。
上面这些都是一个简单的渲染方式,以及渲染的内容替换等,真正让我头疼的是,如果合并的是一个按钮组或者带有事件的东东,这个怎么弄?
踩了一路坑,得到了一种方法,废话不说了,代码如下
children : ( <div> <div class=" spanLink" onClick={ () => this.yourFunction(a,b,c,d)}> 一个带有点击事件的template </div> </div> )
这里重点的是只能用 纯 jsx 语法进行编写,事件推荐使用括号函数进行带入,参数正常传递就可以了。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。