ant-design-vue table嵌套表格,自定义展开图标

背景

近期有一个需求,需要有嵌套表格的场景, 使用 ant-design-vue UI , 嵌套子表格,可能会存在子表格没有数据的情况, 之前没有怎么使用过这个UI库

要解决的问题:

  1. 子表格没有数据,不展示展开图标
  2. 子表格没有数据,不显示

版本说明

使用的环境说明

js 复制代码
"vue": "^2.6.14"
"ant-design-vue": "^1.7.8"
"node": "v14.19.3"

完整代码

html 复制代码
<template>
	<a-table
		:columns="columns"
		:data-source="data"
		:rowSelection="rowSelection"
		:pagination="false"
	>
		<!-- 自定义展开图标 -->
		<template slot="expandIcon" slot-scope="row">
			<!-- 如果嵌套的子表格没有数据,则不展示展开图标 -->
			<template v-if="row.record.list.length">
				<!-- 自定义 换了一个图标 -->
				<!-- <a-icon
				type="plus-circle"
				@click="getRows(row)"
			/> -->

				<!-- 如果需要官网的 ( - + ) 这种图标效果, 稍微改造一下
          expanded  -》 true  表示展开; false 表示收起
         -->

				<a-icon
					type="plus"
					v-show="!row.expanded"
					@click="getRows(row, $event)"
				/>
				<a-icon
					type="minus"
					v-show="row.expanded"
					@click="getRows(row, $event)"
				/>
			</template>
		</template>

		<a-table
                    slot="expandedRowRender"
                    slot-scope="record"
                    :columns="innerColumns"
                    :data-source="record.list"
                    :pagination="false"
                    :rowSelection="childRowSection"
                    v-if="record.list.length"
		>
			<span slot="status" slot-scope="row">
                            <a-badge status="success" />{{ row.status }}
			</span>

			<!-- 操作列 -->
			<span slot="operation" slot-scope="innerRow" class="table-operation">
                            <a-button @click="onGetInnerRow(innerRow, record)">操作</a-button>
			</span>
		</a-table>
	</a-table>
</template>
<script>
const columns = [
	{ title: 'Name', dataIndex: 'name', key: 'name' },
	{ title: 'Platform', key: 'platform' },
	{ title: 'Version', key: 'version' },
	{ title: 'Upgraded', key: 'upgradeNum' },
	{ title: 'Creator', key: 'creator' },
	{ title: 'Date', key: 'createdAt' },
	{ title: 'Action', key: 'operation' },
]

const data = []

data.push({
	key: 1,
	name: '外层的' + 1,
	platform: 'iOS',
	version: '10.3.4.5654',
	upgradeNum: 500,
	creator: 'Jack',
	createdAt: '2014-12-24 23:12:00',
	list: [
		{
			key: 10,
			index: 1,
			date: '2014-5555',
			name: '滴滴滴',
			upgradeNum: '888',
			status: '正常',
		},
		{
			key: 133,
			index: 2,
			date: '2014-12-24 23:12:00',
			name: 'deng的你',
			upgradeNum: '985959',
			status: '正常',
		},
	],
})

data.push({
	key: 2,
	name: '你好-' + 2,
	platform: 'iOS',
	version: '10.3.4.5654',
	upgradeNum: 12323,
	creator: 'Jack',
	createdAt: '阿斯达',
	list: [
		{
			key: 212,
			date: '2014-12-24 23:12:00',
			name: '张安',
			upgradeNum: '阿斯大苏打',
			status: '正常',
		},
	],
})

data.push({
	key: 3,
	name: '空子元素-' + 2,
	platform: 'iOS',
	version: '空的子项',
	upgradeNum: 12323,
	creator: 'Jack',
	createdAt: '2022222',
	list: [],
})

const innerColumns = [
	{ title: '日期', dataIndex: 'date', key: 'date' },
	{ title: '姓名', dataIndex: 'name', key: 'name' },
	{ title: '状态', key: 'state', scopedSlots: { customRender: 'status' } },
	{ title: '更新状态', dataIndex: 'upgradeNum', key: 'upgradeNum' },
	{
		title: 'Action',
		// 使用slot 这里不能要dataIndex
		// dataIndex: 'operation',
		key: 'operation',
		scopedSlots: { customRender: 'operation' },
	},
]

export default {
	data() {
		return {
			data,
			columns,
			innerColumns,
			rowSelection: {
				onSelect(record, selected, selectedRows, nativeEvent) {
					console.log(record)
				},
			},
			childRowSection: {
				onSelect(record, selected, selectedRows, nativeEvent) {
					console.log('子表格')
					console.log(selectedRows)
				},
			},
		}
	},
	methods: {
		getRows(props, event) {
			console.log(props)

			props.onExpand(props.record, event)
		},
		/**
		 * @param {Object} row 子表格的数据行
		 * @param {parentRow} row 父表格行数据
		 */
		onGetInnerRow(row, parentRow) {
			console.log(row)
			console.log(parentRow)
		},
	},
}
</script>

说明: 项目如果没有配置jsx语法的支持,也就是没有配置babel的, 请使用上面 template的写法。

jsx写法

js 复制代码
data() {
    return {
        // jsx 写法
        expandIcon(row) {
           if (!row.expanded) {
           // 收起状态
               return (
                   <a-icon type="plus" onClick="{e => this.getRows(row, e)}"/>
               )
           } else {
           // 展开状态
               return (
                   <a-icon type="minus" onClick="{e => this.getRows(row, e)}"/>
               )
           }
            
        }
    }
}

效果图

相关推荐
空の鱼6 分钟前
js与vue基础学习
javascript·vue.js·学习
鱼樱前端9 分钟前
2025前端SSR框架之十分钟快速上手Nuxt3搭建项目
前端·vue.js
極光未晚18 分钟前
React Hooks 中的时空穿梭:模拟 ComponentDidMount 的奇妙冒险
前端·react.js·源码
Codebee19 分钟前
OneCode 3.0 自治UI 弹出菜单组件功能介绍
前端·人工智能·开源
ui设计兰亭妙微21 分钟前
# 信息架构如何决定搜索效率?
前端
1024小神1 小时前
Cocos游戏中UI跟随模型移动,例如人物头上的血条、昵称条等
前端·javascript
Mapmost1 小时前
告别多平台!Mapmost Studio将制图、发布、数据管理通通搞定!
前端
LaoZhangAI1 小时前
GPT-4o mini API限制完全指南:令牌配额、访问限制及优化策略【2025最新】
前端·后端
前端的日常1 小时前
ts中的type和interface的区别
前端
HYI1 小时前
naive-ui n-data-table 使用踩坑总结
vue.js