1、点击展开当前行,使用当前行的对象渲染基本的信息,使用当前行的id请求获取展开行里的表格数据
![在这里插入图片描述](https://img-blog.csdnimg.cn/e057268d814b4a7794f333c5f7949401.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5b-D6Iul5ZCR6ZizKCrvv6PvuLbvv6Mp,size_20,color_FFFFFF,t_70,g_se,x_16)
2、问题来了:点击第一个展开获取到的数据是正常的,点击第二个,获取到的表格数据会覆盖第一个表格的数据,即最新点击获取的展开行的表格数据覆盖前面打开的行的表格数据
![在这里插入图片描述](https://img-blog.csdnimg.cn/913d67f00a1647a1a62059c16b8c0f75.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5b-D6Iul5ZCR6ZizKCrvv6PvuLbvv6Mp,size_20,color_FFFFFF,t_70,g_se,x_16)
3、代码:
父组件:
<a-table
:columns="columns"
:dataSource="dataSource"
:row-selection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
}"
:pagination="pagination"
rowKey="id"
:loading="dataLoad"
@change="onChange"
@expand="getDeviceData"
>
<span slot="action" slot-scope="record">
<a @click="addNew(true, record)">修改 </a>|
<a @click="deleteRecord(record.id)">删除 </a>
</span>
<template slot="expandedRowRender" slot-scope="record">
<device-content
ref="detail"
:records="record"
:tableData="tableData"
/>
</template>
</a-table>
// 展开行
async getDeviceData(expanded, record) {
if (expanded) {
this.getDeviceFn(record.id)
}
},
// 获取关联的设备数据
async getDeviceFn(id) {
let res = await this.$http(
this.$url.GET_ALL_RELATION_DEVICE_DATA + id,
"get"
);
if (res.data.code === 200) {
let { data } = res.data;
this.tableData = data;
}
},
子组件:
<div class="desBm">
<a-table
:columns="columns"
:dataSource="$attrs.tableData"
rowKey="id"
:pagination="false"
>
<span slot="action" slot-scope="records">
<a href="javascript:void(0);" @click="goDevice(records.deviceCode)">查看设备</a>
</span>
</a-table>
</div>
4、展开的时候,给最外层表格数据添加属性,属性的值就是子组件的表格数据,使用延迟改变子组件tableShow的值,也可以实现需求(弊端:数据量大、网络不好时、延迟的时间不好定义,不严谨)
父组件:
<template slot="expandedRowRender" slot-scope="record">
<device-content
ref="detail"
:records="record"
/>
</template>
// 展开行
async getDeviceData(expanded, record) {
if (expanded) {
let index = 0
this.dataSource.forEach((t,i)=>{
t.id==record.id ? index = i : ''
})
record.tableData = await this.getDeviceFn(record.id);
this.$set(this.dataSource , index, record)
}
},
// 获取关联的设备数据
async getDeviceFn(id) {
let res = await this.$http(
this.$url.GET_ALL_RELATION_DEVICE_DATA + id,
"get"
);
if (res.data.code === 200) {
let { data } = res.data;
return data;
}else{
return []
}
},
子组件:
<div class="desBm" v-if="tableShow">
<a-table
:columns="columns"
:dataSource="records.tableData"
rowKey="id"
:pagination="false"
>
<span slot="action" slot-scope="records">
<a href="javascript:void(0);" @click="goDevice(records.deviceCode)">查看设备</a>
</span>
</a-table>
</div>
mounted() {
setTimeout(() => {
console.log(this.records.tableData)
this.tableShow = true;
}, 1000);
},
5、解决一: 拿到最外层表格的数组时,添加一个属性并赋值tableShow: false,在展开行的时候,给当前行的tableShow: true, 通过this.$set更新当前行数据,子组件表格通过判断这个属性再渲染,完整代码:
父组件:
<template slot="expandedRowRender" slot-scope="record">
<device-content
ref="detail"
:records="record"
/>
</template>
// 展开行事件
async getDeviceData(expanded, record) {
if (expanded) {
let index = 0
this.dataSource.forEach((t,i)=>{
t.id==record.id ? index = i : ''
})
record.tableData = await this.getDeviceFn(record.id); // 调用获取子组件表格数据的方法
record.tableShow = true
this.$set(this.dataSource , index, record)
}
},
// 获取子组件表格数据
async getDeviceFn(id) {
let res = await this.$http(
this.$url.GET_ALL_RELATION_DEVICE_DATA + id,
"get"
);
if (res.data.code === 200) {
let { data } = res.data;
return data;
}else{
return []
}
},
子组件deviceContent:
<div class="desBm" v-if="tableShow">
<a-table
:columns="columns"
:dataSource="records.tableData"
rowKey="id"
:pagination="false"
>
<span slot="action" slot-scope="records">
<a href="javascript:void(0);" @click="goDevice(records.deviceCode)">查看设备</a>
</span>
</a-table>
</div>
props: ['records'],
6、解决二: 子组件使用watch监听父组件传来的值,原理跟第一种相同,就是给响应式的数组添加新属性,通过$set更新数组
父组件:
async getData(query = {}) {
this.dataLoad = true;
let res = await this.$http(this.$url.GET_STATION_MANAGE_LIST, "get", {
pageNum: this.pagination.current,
pageSize: this.pagination.pageSize,
...query,
}).catch(() => {
this.dataLoad = false;
});
this.dataLoad = false;
let { data } = res;
if (data.code == 200) {
this.dataSource = data.data.rows.map(i=>({...i,tableData:[]})); // 添加属性且赋值tableData: []
this.pagination.current = data.data.currentPage;
this.pagination.total = data.data.total;
}
},
// 展开行
async getDeviceData(expanded, record) {
if (expanded) {
let index = 0
this.dataSource.forEach((t,i)=>{
t.id==record.id ? index = i : ''
})
record.tableData = await this.getDeviceFn(record.id); // 赋值
this.$set(this.dataSource , index, record); // 更新
}
},
// 获取关联的设备数据
async getDeviceFn(id) {
let res = await this.$http(
this.$url.GET_ALL_RELATION_DEVICE_DATA + id,
"get"
);
if (res.data.code === 200) {
let { data } = res.data;
return data;
}else{
return []
}
},
子组件:
<div class="desBm" v-if="tableShow">
<a-table
:columns="columns"
:dataSource="records.tableData"
rowKey="id"
:pagination="false"
>
<span slot="action" slot-scope="records">
<a href="javascript:void(0);" @click="goDevice(records.deviceCode)">查看设备</a>
</span>
</a-table>
</div>
data() {
return {
columns,
showImg: false,
tableShow:false,
}
},
watch:{
records:{
handler: function(val){
if(val) {
this.tableShow = true
}
},
deep:true,
immediate: true
}
},
7、深入了解vue响应式原理才能更好理解、解决问题! 最终效果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/57f2c46a2c204489b1c55a68cd02edd3.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5b-D6Iul5ZCR6ZizKCrvv6PvuLbvv6Mp,size_20,color_FFFFFF,t_70,g_se,x_16)
不要活在别人的世界里,却也不是自我为中心!