情景介绍
父组件调用接口获取数据,然后通过props
传值给子组件,子组件拿到数据后渲染到 el-table 表格组件中。
结果子组件没有将数据渲染到表格中,但是控制台打印是获取到数据的。
问题分析
先看父组件代码:
<template>
<div class="main-container">
<Aside></Aside>
<Table :userData="list"></Table>
</div>
</template>
<script>
import Aside from '@/components/PublicAddrList/Aside'
import Table from '@/components/PublicAddrList/Table'
import {allUserContact} from '@/api/publicAddr'
export default {
components: {
Aside,
Table
},
data () {
return {
list: [],
}
},
created () {
this.getAllUser();
},
methods: {
getAllUser () {
allUserContact().then(res => {
if(res.rows && res.rows.length > 0) {
res.rows.forEach(item => {
let obj = {
"name": item.name,
"sex": item.sex,
"mobile": item.mobile,
"email": item.email,
"loginFlag": item.loginFlag,
"accountFlag": item.accountFlag,
"imgPath": item.imgPath
}
this.list.push(obj);
});
}
})
},
}
}
</script>
子组件接收数据部分的代码:
<script>
export default {
props: {
userData: {
type: Array,
default: () => []
},
},
created () {
this.getUserData();
},
data () {
return {
tableData: [],
pagenum:1, // 当前页数
pagesize:12, // 每页条目数
total: 0,
multipleSelection: [],
}
},
methods: {
/* 接收父组件Main从接口获取到的数据 */
getUserData () {
this.tableData = this.userData;
this.total = this.tableData.length;
},
}
}
</script>
一开始我以为是因为子组件 created 的时候还没接收到父组件的传值,所以把函数放到 mounted 里调用,结果还是没接收到。
而且通过查阅资料,传值应该就是从页面加载开始的。通过打印不同地方的数据,应该是父组件还没调用接口的时候子组件就渲染好了,导致子组件渲染的时候还没有数据,等子组件渲染好了父组件才调用了接口,所以出现data里打印有数据,但是页面上没渲染的情况。
解决方案
在网上查看,解决问题有两个途径:
- 父组件调用完接口再渲染子组件。
- 子组件监听接收数据的变化,然后强制重新渲染
我这里先试了第一种方法。通过v-if
来控制子组件的渲染,设置一个 flag ,值为 false ,等调用完接口获取到数据再赋值为 true。
<template>
...
<Table v-if="flag" :userData="list"></Table>
...
</template>
<script>
export default {
...
data () {
return {
flag: false
}
}
methods: {
getAllUser () {
allUserContact().then(res => {
if(res.rows && res.rows.length > 0) {
res.rows.forEach(item => {
let obj = {
"name": item.name,
"sex": item.sex,
"mobile": item.mobile,
"email": item.email,
"loginFlag": item.loginFlag,
"accountFlag": item.accountFlag,
"imgPath": item.imgPath
}
this.list.push(obj);
});
this.flag = true;
}
})
},
}
}
</script>