問題描述:
頁面渲染成功,但在控制檯中卻出現類似如下的報錯:
原因:
一般出現這種報錯,原因就是在接口數據未獲取之前,使用了深層屬性,即多層的 . ,如定義好data:
data() {
return {
chartData: {
top: {},
bottom: {},
},
}
}
但在模板中卻使用了 top.columns[0] 這種深層屬性,這時top爲空,top.columns爲undefined,top.columns[0]自然會報錯。
解決辦法:
解決這種問題的方法也比較簡單,就是在使用深層屬性的html節點上使用v-if,如:
<el-radio-group v-model="formOption.period" @change="initAllChart">
<el-radio-button :label="topPeriods[0]['id']" v-if="topPeriods[0]['id']"
style="position: absolute;top: 10px;left: 200px;">
{{ topPeriods[0]['name'] }}
</el-radio-button>
</el-radio-group>
這樣,在未獲取接口數據之前,vue實例不會渲染該節點,也就不會報錯了。
如果在template中使用v-for,則需要將變量定義在data中,不可定義在computed中,因爲在data中可以定義數據類型,computed則不能定義,如下,定義topPeriod是爲數組,則在v-for中自動識別,空數組不渲染。
data() {
return {
topPeriods : []
}
},
<template v-for="(topPeriod, index) in topPeriods">
<el-radio-button :label="topPeriod['id']" v-if="topPeriod"
:style="buttonStyle(index)">
{{ topPeriod['name'] }}
</el-radio-button>
</template>
總結:
1 在使用未定義屬性的節點上使用v-if。
2 在data中定義變量類型。
注意點:
這裏有幾個需要注意的點,也是我踩過的坑:
1 在上述例子中,如果父節點上使用 v-if="topPeriods[0]" 或 v-if="topPeriods" , Vue 仍會報錯,我在查詢到的一些博客中提出這也是解決問題的一種方法,但其實並不能解決問題。
2 也有一些博客提出,將mounted()修改爲created(),也就是在Vue生命週期中的created階段去獲取所有數據,然後更新dom時就不會報錯了,這種方法也不能解決問題,因爲一般異步調用在mounted()執行後並未完成,他就繼續更新數據,並在update()階段實時更新dom,同樣會報錯,測試如下圖:
我在vue生命週期中打印提示,可以看出,無論是created()還是mounted()執行完之後,仍會執行接口調用數據,從而引起錯誤。
beforeCreate() {
console.log("beforecreated")
},
beforeMount() {
console.log("beforeMounted")
},
mounted() {
console.log("mounted");
},
created() {
console.log('createdBegin');
this.getRegions();
this.getYears();
this.getTypes();
this.getPeriods();
this.initFullScreenChart();
console.log('createdEnd');
},
beforeDestroy() {
console.log("beforeDestroy")
},
destroyed() {
console.log("destoryed");
},
beforeUpdate() {
console.log("beforeUpdate");
},
updated() {
console.log("update");
},
watch : {
'formData.years' : function (newVal) {
console.log('years 更新了')
},
'formData.regions' : function (newVal) {
console.log('regions 更新了')
},
'formData.types' : function (newVal) {
console.log('types 更新了')
},
'formData.periods' : function (newVal) {
console.log('periods 更新了')
},
'chartData.top' : function ( ) {
console.log('top更新了');
},
'chartData.bottom' : function () {
console.log('bottom更新了');
}
}