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更新了');
    }
}

 

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