VUE父組件異步獲取數(shù)據(jù),子組件接收的值為空的問題
在vue中引用Echarts圖表,動態(tài)渲染數(shù)據(jù)時一直不展示數(shù)據(jù)。
父組件異步請求獲取數(shù)據(jù)傳給子組件,子組件接收的打印的真實的值卻為初始值,如下所示
- 父組件

- 子組件

原因的話:
加載渲染的時候,請求是一個異步的操作,子組件在拿到數(shù)據(jù)前就渲染了,子組件沒有監(jiān)控到值得變化
父子組件加載渲染過程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
昨天晚上遇到這個問題,在網(wǎng)上找了是下面三個方法:
- 在子組件用watch監(jiān)控父組件傳遞過來值得變化,設(shè)置deep:true【deep官方定義:為了發(fā)現(xiàn)對象內(nèi)部值的變化,可以在選項參數(shù)中指定 deep: true。注意監(jiān)聽數(shù)組的變更不需要這么做?!?/li>
- 在父組件使用v-if,當(dāng)請求結(jié)束之后,改變v-if內(nèi)變量的值,加載子組件
- 使用vuex全局狀態(tài)管理,這個沒嘗試
上面三種方法的話:
- 第一種是最簡潔明了的,但是昨天晚上第一種方法一直不成功,可能是語法寫錯了,今天早上上班試了一下才成功;
- 因為我們做的是數(shù)據(jù)展示,所以第二種就不適合我們的需求;
- 第三種的話我就沒試,網(wǎng)上的解決流程感覺太麻煩了;
這樣的話,其實昨天就沒解決這個問題,下班回去的時候換了一個思路想了這個問題,這個原因就是父組件異步請求沒有更新子組件的數(shù)據(jù)值,其實我們可以手動的更新子組件的值,在父組件異步請求拿到數(shù)據(jù)時,在成功回調(diào)賦值的時候,手動的調(diào)用子組件的方法,并把數(shù)據(jù)當(dāng)成參數(shù)傳遞過去,子組件的處理就是在該方法內(nèi)手動的刷新對象的,今天早上上班按照該思路,發(fā)現(xiàn)可以解決這個問題。
下面就介紹一下vue父組件異步獲取數(shù)據(jù),子組件接收的值為空三種解決方法:
1.父組件異步獲取數(shù)據(jù),調(diào)用子組件方法重新賦值 【第二種方法不行,推薦使用該方法】
- 父組件
<template>
<div class="index">
//設(shè)置ref的值,下面調(diào)用
<ChartBasicLine :chartObj="chartRegUser" :ref="chartRegUser.type" />
</div>
</template>
<script>
import { getStatUser } from '@/api/data'
import ChartBasicLine from '@/components/Chart/ChartBasicLine'
export default {
components: {
ChartBasicLine
},
data() {
return {
chartRegUser: {
num: 0,
percent: '0.00%',
status: 0,
type: 'reg_user',
tips: '新增用戶',
title: '新增用戶(NU)',
link: '',
isShow: false,
xData: [],
yData: []
}
}
},
created() {
this.getStatUser()
},
methods: {
getStatUser() {
const _this = this
// 異步請求獲取數(shù)據(jù)
getStatUser().then(res => {
if (res.code === 0) {
// 賦值
_this.$set(_this.chartRegUser, 'xData', res.data['x_data'])
_this.$set(_this.chartRegUser, 'yData', res.data['y_data'])
// 這里是調(diào)用子組件的refresh的方法
_this.$refs[_this.chartRegUser.type].refresh(res.data)
}
})
}
}
}
</script>
- 子組件
<template>
<div class="ChartBasicLine">
<div
:ref="chartObj.type"
class="chart_show"
/>
</div>
</template>
<script>
export default {
name: 'ChartBasicLine',
props: {
chartObj: {
type: Object
}
},
data() {
return {
option: {
tooltip: {
trigger: 'axis'
},
grid: {
top: '22px',
left: '40px',
right: '30px'
},
xAxis: {
type: 'category'
},
yAxis: {
type: 'value'
},
series: [{
type: 'line'
}]
},
myChart: {}
}
},
mounted() {
this.showChart()
},
methods: {
showChart() {
this.myChart = this.$echarts.init(this.$refs[this.chartObj.type])
this.option.xAxis['data'] = this.chartObj.xData
this.option.series[0]['data'] = this.chartObj.yData
this.myChart.setOption(this.option)
},
/**
* 父組件給圖表信息重新賦值,并重新刷新圖表
*/
refresh(data) {
this.option.xAxis['data'] = data['x_data']
this.option.series[0]['data'] = data['y_data']
this.myChart.setOption(this.option)
}
}
}
</script>
<style>
.ChartBasicLine .el-input {
margin-right: 0 !important;
}
</style>
2.子組件內(nèi)使用watch監(jiān)控對象值變化時重新賦值【推薦】
- 子組件
<template>
<div class="ChartBasicLine">
<div
:ref="chartObj.type"
class="chart_show"
/>
</div>
</template>
<script>
export default {
name: 'ChartBasicLine',
props: {
chartObj: {
type: Object
}
},
data() {
return {
option: {
tooltip: {
trigger: 'axis'
},
grid: {
top: '22px',
left: '40px',
right: '30px'
},
xAxis: {
type: 'category'
},
yAxis: {
type: 'value'
},
series: [{
type: 'line'
}]
},
myChart: {}
}
},
watch: {
chartObj: { // 監(jiān)控該變量,重新賦值并刷新圖表
handler(newVal, oldVal) {
this.chartObj = newVal
this.showChart()
},
deep: true // 必須設(shè)置
}
},
mounted() {
this.showChart()
},
methods: {
showChart() {
this.myChart = this.$echarts.init(this.$refs[this.chartObj.type])
this.option.xAxis['data'] = this.chartObj.xData
this.option.series[0]['data'] = this.chartObj.yData
this.myChart.setOption(this.option)
}
}
}
</script>
3.父組件內(nèi)使用v-if渲染子組件【不推薦】
- 父組件
<template>
<div class="index">
// 通過v-if來控制子組件顯示
<ChartBasicLine v-if="isShow" />
</div>
</template>
<script>
import { getStatUser } from '@/api/data'
import ChartBasicLine from '@/components/Chart/ChartBasicLine'
export default {
components: {
ChartBasicLine
},
data() {
return {
chartRegUser: {
num: 0,
percent: '0.00%',
status: 0,
type: 'reg_user',
tips: '新增用戶',
title: '新增用戶(NU)',
link: '',
isShow: false,
xData: [],
yData: []
},
isShow: false // 控制子組件是否展示
}
},
created() {
this.getStatUser()
},
methods: {
getStatUser() {
const _this = this
getStatUser().then(res => {
if (res.code === 0) {
_this.$set(_this.chartRegUser, 'xData', res.data['x_data'])
_this.$set(_this.chartRegUser, 'yData', res.data['y_data'])
// 異步請求獲取數(shù)據(jù),展示子組件
_this.isShow = true
}
})
}
}
}
</script>VUE中數(shù)組賦空值注意事項
在js或者Vue中,給數(shù)組賦空值不可以直接賦空值,例如:
var list = {a:'12',b:'34'};// 創(chuàng)建一個數(shù)組
list = [];// 數(shù)組賦空值否則會在再次賦值的時候報錯
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue2.0.js的多級聯(lián)動選擇器實現(xiàn)方法
下面小編就為大家分享一篇vue2.0.js的多級聯(lián)動選擇器實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02

