前端为Ant Design Vue 版本为1.6.2,使用的是vue2
Ant Design Vue中 a-table 嵌套子表格,说的可能稍微墨迹了点,不过重点内容都说的比较详细,利于新人理解,高手可以自取完整代码
内容概述:
- 完成样式及完整代码展示
- 子表格嵌套
- 只打开一个嵌套表格
完成样式及完整代码展示
下图为官网图,会在每行最前面多一个加号,点击后会展开,看到子表格的数据
<template
>
<div
>
<a
-card
>
<a
-table
:columns
="columns" :data
-source
="datasource" :bordered
="true" :expandedRowKeys
="expandedRowKeys"
@expand
="getInnerData" :pagination
="pagination">
<a
-table slot
="expandedRowRender" slot
-scope
="text" :columns
="innerColumns" :data
-source
="inndata"
:pagination
="false"></a
-table
>
<span slot
="operation" slot
-scope
="text, record">
<a
-button type
="primary" icon
="unordered-list" @click
="getData(record)">
详情
</a
-button
>
</span
>
</a
-table
>
</a
-card
>
</div
>
</template
>
<script
>
import { axios
} from '@/utils/request'
const columns
= [
{
title: '序号',
dataIndex: 'id',
key: 'id',
},
。。。。。中间省略
{
title: '操作',
key: 'operation',
width: '80px',
scopedSlots: { customRender: 'operation' },
},
];
const innerColumns
= [
{
title: '子表单列',
dataIndex: 'XXX',
key: 'XXX',
},
];
const inndata
= [];
export default {
data() {
return {
datasource: [],
columns
,
innerColumns
,
inndata
,
expandedRowKeys:[],
pagination: {
//分页
showSizeChanger: true, //是否分页
curPageSizeIndex: 0,
pageSize: 10, //一页显示多少条
// total: 1, //总条数
current: 1, //当前显示页面
pageSizeOptions: ['10', '20', '30'],
showTotal: (total) => `共计 ${total}条`, //显示总数
onShowSizeChange: (current, pagesize) => {
this.pagination
.current
= current
this.pagination
.pageSize
= pagesize
this.options
.offset
= (current
- 1) * pagesize
this.options
.limit
= pagesize
this.refreshData()
},
onChange: (current, pageSize) => {
this.pagination
.current
= current
this.options
.offset
= (current
- 1) * pageSize
this.options
.limit
= pageSize
this.refreshData()
},
},
}
},
mounted() {
this.refreshData()
},
methods: {
refreshData() {
axios({
url: 'url',
method: 'post',
}).then((res) => {
if (res
.errCode
> 0) {
this.$notification
.error({
message: '错误信息',
description: res
.errMsg
,
})
return
}
console
.log(res
, '数据')
this.datasource
= res
})
},
getInnerData(expanded, record) {
this.expandedRowKeys
=[]
if (expanded
) {
var b
= ''
b
=(record
.id
-1).toString()
this.expandedRowKeys
.push(Number(b
.slice(-1)))
this.inndata
= [];
this.inndata
.push(this.datasource
[record
.id
- 1])
}
},
getData(record) {
console
.log(record
);
},
},
}
</script
>
<style scoped
>
</style
>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
子表格嵌套
子格嵌套从代码层简单理解就是一个中套了一个,即,当然,这只是一个简单理解,并不是这样写,要在其中添加一些东西。
抛开一些配置项,解释下:
<template
>
<div
>
<a
-card
>
// 这里开始是父表格组件,columns -> 父级列名,datasource -> 父级表中的数据, @expand="getInnerData" -> 点开子表单的操作函数,pagination -> 分页的设置
<a
-table
:columns
="columns" :data
-source
="datasource"
@expand
="getInnerData" :pagination
="pagination">
// 这里开始是子表格组件,slot="expandedRowRender" 重点,必须有,innerColumns-> 子级列名,inndata-> 子级表中的数据,
<a
-table slot
="expandedRowRender" slot
-scope
="text" :columns
="innerColumns" :data
-source
="inndata"
:pagination
="false"></a
-table
>// 这里是子表格组件结尾
// 这里是父表格span,不用的可以删掉
<span slot
="operation" slot
-scope
="text, record">
<a
-button type
="primary" icon
="unordered-list" @click
="getData(record)">
详情
</a
-button
>
</span
>
</a
-table
>// 这里是父表格组件结尾
</a
-card
>
</div
>
</template
>
<script
>
// 数据请求axios
import { axios
} from '@/utils/request'
// 设置父级列名
const columns
= [
{
title: '序号',
dataIndex: 'id',
key: 'id',
},
。。。。。中间省略
{
title: '操作',
key: 'operation',
width: '80px',
scopedSlots: { customRender: 'operation' },
},
];
// 设置子级列名
const innerColumns
= [
{
title: '子表单列',
dataIndex: 'XXX',
key: 'XXX',
},
];
// 设置子级数据,写下面data里也行
const inndata
= [];
export default {
data() {
return {
datasource: [],
columns
,
innerColumns
,
inndata
,
pagination: {
//分页
showSizeChanger: true, //是否分页
curPageSizeIndex: 0,
pageSize: 10, //一页显示多少条
// total: 1, //总条数
current: 1, //当前显示页面
pageSizeOptions: ['10', '20', '30'],
showTotal: (total) => `共计 ${total}条`, //显示总数
onShowSizeChange: (current, pagesize) => {
this.pagination
.current
= current
this.pagination
.pageSize
= pagesize
this.options
.offset
= (current
- 1) * pagesize
this.options
.limit
= pagesize
this.refreshData()
},
onChange: (current, pageSize) => {
this.pagination
.current
= current
this.options
.offset
= (current
- 1) * pageSize
this.options
.limit
= pageSize
this.refreshData()
},
},
}
},
mounted() {
// 进入页面直接运行的函数
this.refreshData()
},
methods: {
// 异步请求获取数据
refreshData() {
axios({
url: 'url',
method: 'post',
}).then((res) => {
if (res
.errCode
> 0) {
this.$notification
.error({
message: '错误信息',
description: res
.errMsg
,
})
return
}
console
.log(res
, '数据')
// 将数据赋值给父级表格
this.datasource
= res
})
},
// 点开子级表格(就是点击那个加号)触发的函数
getInnerData(expanded, record) {
// 判断是否点开
if (expanded
) {
// 点开后执行。。。
// 先将子级表格数据清空,否则之前点开别的行的数据也会在里面
this.inndata
= [];
// 再将父级点击的那一行的数据(record)给子级数据存进去,具体情况根据自己需求更改
this.inndata
.push(record
)
}
},
// 点击父级表格表格span,也就是那个“详情”按钮触发的函数
getData(record) {
console
.log(record
);
},
},
}
</script
>
<style scoped
>
</style
>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
通过上述操作会发现能够实现基本的子表格嵌套,但是会发现点开一个子表单后,再点一个,两个都会打开,但是里面的子表格数据是相同的,这就是个很大的问题,为了解决这个问题,请看下面,这个在官网没直接写出来,API里有相关的参数,现在告诉你应该怎样操作
只打开一个嵌套表格
为了防止点开多个子表格内容相同,再结合我自己的使用场景,我只需要展开一个子表格就行,也就是说点开新的子表格后,原来的子表格自动关闭
下面把需要改动的代码片段给你们:
1. 父级中的修改内容
// 添加 :expandedRowKeys="expandedRowKeys" 目的是使expandedRowKeys只有最新点开子表单的key
<a
-table
:columns
="columns" :data
-source
="datasource" :bordered
="true" :expandedRowKeys
="expandedRowKeys"
@expand
="getInnerData" :pagination
="pagination">
<a
-table slot
="expandedRowRender" slot
-scope
="text" :columns
="innerColumns" :data
-source
="inndata"
:pagination
="false"></a
-table
>
<span slot
="operation" slot
-scope
="text, record">
<a
-button type
="primary" icon
="unordered-list" @click
="getData(record)">
详情
</a
-button
>
</span
>
</a
-table
>
2. 在data里加上空的 expandedRowKeys
export default {
data() {
return {
datasource: [],
columns
,
innerColumns
,
inndata
,
// 添加空的expandedRowKeys
expandedRowKeys:[],
。。。。。。
3. 修改getInnerData函数
getInnerData(expanded, record) {
// 先将expandedRowKeys数据清空
this.expandedRowKeys
=[]
if (expanded
) {
// 将父级的第几条数据传到expandedRowKeys里,我这用的是数据表里的id处理的,我的id是从1开始
// 我这是一页十条数据,要放入0-9,第一条是0,第十条是9,一定要是数字格式
// 再一个,注意下,假设使用的是数据中的第45条,record.id=45
// 但是传入 expandedRowKeys 只能是0-9,且是数字格式,那么应该将数字4传到expandedRowKeys中
// 因为record.id=45这条数据,在表格中的第五行,应该是4
// 所以有了下面的record.id-1,再转成字符串格式,取最后一位,再转成数字
// 也有人用key,id能够获取到,不过我没弄成功,就这样吧,实现功能就行
var b
=(record
.id
-1).toString()
this.expandedRowKeys
.push(Number(b
.slice(-1)))
// 下面两行说过,我就把注释直接粘过来了
// 先将子级表格数据清空,否则之前点开别的行的数据也会在里面
this.inndata
= [];
// 再将父级点击的那一行的数据(record)给子级数据存进去,具体情况根据自己需求更改
this.inndata
.push(record
)
}
},
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21