vue3 组合式 ant.design组件Table嵌套表格,从后端获取数据并动态渲染

在根据官方文档使用ant.design中的嵌套表格时,发现官方文档很多地方都不够详细。在过程中踩了不少坑,例如:

子表如何获取父表的数据?

如何获取子表的行索引?

如何让子表的数据源来自父表该行的数据?

总之,最后还是磕磕绊绊做完了功能,于是第一时间把代码整理出来以作分享。

首先,后端返回的数据是json格式。

后端返回数据格式如下:

{
    "result": true,
    "errorCode": null,
    "errorMsg": null,
    "data": [
        {
            "id": "001",
            "name": "A",
            "releaseVersion": "v2.00.02",
            "subSystem": "a",
            "type": "edit",
            "history": [
                {
                    "editVersion": 1,
                    "timestamp": "2023/05/08 12:23",
                    "comment": "备注1.1"
                },
                {
                    "editVersion": 2,
                    "timestamp": "2023/05/08 12:23",
                    "comment": "备注1.2"
                }
            ]
        },
        {
            "id": "002",
            "name": "B",
            "releaseVersion": "v2.00.01",
            "subSystem": "b",
            "type": "edit",
            "history": [
                {
                    "editVersion": 1,
                    "timestamp": "2023/05/08 12:23",
                    "comment": "备注2.1"
                },
                {
                    "editVersion": 2,
                    "timestamp": "2023/05/08 12:23",
                    "comment": "备注2.2"
                }
            ]
        }
    ],
    "recordsTotal": 123
}

前端渲染的数据格式如下:

[
    {
        "key": 0,
        "name": "A",
        "subSystem": "a",
        "type": "edit",
        "expand": " ",
        "innerDatas": [
            {
                "key": 0,
                "ID": "001",
                "version": "v2.00.021",
                "editComment": "备注1.1",
                "editTime": "2023/05/08 12:23",
                "more": " "
            },
            {
                "key": 0,
                "ID": "001",
                "version": "v2.00.022",
                "editComment": "备注1.2",
                "editTime": "2023/05/08 12:23",
                "more": " "
            }
        ]
    },
    {
        "key": 1,
        "name": "B",
        "subSystem": "b",
        "type": "edit",
        "expand": " ",
        "innerDatas": [
            {
                "key": 1,
                "ID": "002",
                "version": "v2.00.011",
                "editComment": "备注2.1",
                "editTime": "2023/05/08 12:23",
                "more": " "
            },
            {
                "key": 1,
                "ID": "002",
                "version": "v2.00.012",
                "editComment": "备注2.2",
                "editTime": "2023/05/08 12:23",
                "more": " "
            }
        ]
    }
        ]

代码:

<template>

    <div id="main">

        <a-table>

            <template #expandedRowRender="{record}"> 
//这一行代码的意思是添加了一个插槽,#expandedRowRender="{record, index, indent, expanded}",template里面的元素可以使用大括号内的值。其中record是父表内一行的数据,index是行的索引,indent是缩进,expanded表示是否展开。

                <div class="child">

                    <a-table :columns="innerColumns" :data-source="record.innerDatas" >


//表示子表的数据源来自父表record一行数据的innerDatas

                        <template #bodyCell="{ text, record, index, column}"> 
//text表示该行该列也就是这个单元格内的值,record表示子表一行的数据,index表示子表行的索引,column表示子表的列。同样的,该插槽放在父表内表示的就是父表的数据。

                            <template v-if="column.key === 'more'"> 
//这表示子表里column.key为more的这一列,都显示“详细”

                                   <a @click="cilikRow = index, modalVisible = cilikRow > -1" >

                                    详细

                                </a>

                            </template>

                        </template>

                    </a-table>

                    <div class="createModel" ref="createModel">

                        <a-modal v-model:visible="modalVisible" title=" ">

                            <p class="modal-editComment">{
   
   { dataList[0].innerDatas[cilikRow.valueOf()].editComment }}</p> 


//一个a-modal弹窗,当点击“详细”时显示子表中editComment的内容

                        </a-modal>

                    </div>

                </div>

            </template>

        </a-table>

    </div>

</template>

<script lang="ts">

import { DownOutlined } from '@ant-design/icons-vue';

import { defineComponent } from 'vue';

import axios from 'axios';



const cilikRow = ref<Number>(-1)

const columns = [ //父表的列设置

    { title: '标题', dataIndex: 'name', key: 'name', className: 'thChange', width: 400 },

    { title: '副标题', dataIndex: 'subSystem', key: 'subSystem', className: 'thChange', width: 400 },

    { title: '类型', dataIndex: 'type', key: 'type', className: 'thChange', width: 550 },

    { title: '  ', dataIndex: 'expand', key: 'expand', className: 'thChange', expandFixed: 'right' },

];

const innerColumns = [ //子表的列设置

    { title: 'ID', dataIndex: 'ID', key: 'ID', className: 'thColor', width: 100 },

    { title: '版本', dataIndex: 'version', key: 'version', width: 100 },

    { title: '编辑备注', dataIndex: 'editComment', key: 'editComment', ellipsis: true, width: 250 },

    { title: '编辑日期', dataIndex: 'editTime', key: 'editTime', width: 150 },

    { title: '', dataIndex: 'more', key: "more" }

];

interface DataItem { //父表的数据类型定义,我在这里直接把子表的内容放在了父表中

    key: number;

    name: string;

    subSystem: string;

    type: string;

    expand: any;

    innerDatas: innerDataItem[]

}

interface innerDataItem { //子表的数据类型定义

    key: number;

    ID: string;

    version: string;

    editComment: string;

    editTime: string;

    more: string

}

let innerData= reactive<Array<innerDataItem>>([])  //定义一个innerDataItem类型的响应式数组存放子表的数据

const dataList = reactive<Array<DataItem>>([]) //定义一个DataItem类型的响应式数组存放父表的数据

axios.get('http://127.0.0.0/Test/Test123.json')

    .then((res) => {

        for (let i = 0; i < res.data.data.length; i++) {

            innerData = [];    //每次循环将子表数据清空 确保子表数组中的只有父表这一行对应的子表数据而不是子表所有的数据

            for (let j = 0; j < res.data.data[i].history.length; j++) { //子表数据存入

                    innerData.push({

                        key: i,

                        ID: res.data.data[i].id,

                        version: res.data.data[i].releaseVersion + res.data.data[i].history[j].editVersion,

                        editComment: res.data.data[i].history[j].comment,

                        editTime: res.data.data[i].history[j].timestamp,

                        more: " "

                    })

                }



            dataList.push({ //父表数据存入

                key: i,

                name: res.data.data[i].name,

                subSystem: res.data.data[i].subSystem,

                type: res.data.data[i].type,

                expand: " ",

                innerDatas:innerData               

            })                     

        }      

        console.log(dataList)

    })

const modalVisible = ref<boolean>(false);

export default defineComponent({

    components: {

        DownOutlined,

    },

    setup() {

        return {

            modal: false,

            centerDialogVisible: false,

            modalVisible,

            dataList,

            columns,

            innerColumns,

            innerData,

            cilikRow,

        };

    },

});

</script>

猜你喜欢

转载自blog.csdn.net/defined_/article/details/130573296