Vue 中報錯 : Error in render: "TypeError: Cannot read property 'xxx' of undefined

問題描述:

頁面渲染成功,但在控制檯中卻出現類似如下的報錯:

原因:

一般出現這種報錯,原因就是在接口數據未獲取之前,使用了深層屬性,即多層的 . ,如定義好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更新了');
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章