问题描述
自定义了一个component
组件给父组件调用,数据功能都挺正常的,但是浏览器控制台中会报错:
[Vue warn]: Error in render: "TypeError: Cannot read property 'g1' of undefined"
found in
---> <Gauge> at src/components/Gauge.vue
<BTab>
<BTabs>
<Home> at src/views/Home.vue
<App> at src/App.vue
<Root>
父组件
调用Gague
组件的时候为其属性gdata
传入数据类型为Object
的gague1
数据
<template>
<div>
<gauge :gdata="gague1"></gauge>
</div>
</template>
<script>
import ECharts from 'vue-echarts'
import 'echarts/lib/chart/bar'
import 'echarts/lib/chart/line'
import 'echarts/lib/component/legend'
import 'echarts/lib/component/tooltip'
import Gauge from '../components/Gauge'
export default {
components: {
'v-chart': ECharts,
'gauge': Gauge,
},
data () {
return {
gague1: {
g1: {
min: -100,
max: 100,
data: [
{
name: '数据1',
value: 3.5,
}],
}
}
// ...
}
</script>
子组件Gauge.vue
<template>
<b-row>
<b-col md="4">
{{ gdata.g1}}
<v-chart></v-chart>
</b-col>
<b-col md="4">
内同2
</b-col>
<b-col md="4">
内同3
</b-col>
</b-row>
</template>
<script>
import ECharts from 'vue-echarts'
import 'echarts/lib/chart/gauge'
export default {
name: 'Gauge',
components: {
'v-chart': ECharts,
},
props: ['gdata']
}
</script>
<style scoped>
</style>
解决办法
参考Github上的Issue: https://github.com/vuejs/vue/issues/1032
子组件Gauge.vue
中定义属性props
的时候加上默认值就可以了,使用了ES6的箭头语法
props: {
gdata: {
type: Object,
default: () => {
return {
g1: {},
}
},
},
},
补充
又翻到这篇文章:
https://juejin.im/post/5c408be9f265da614f709043
针对ajax异步请求,这样的错误原因其实就是因为返回结果没赶上dom节点的渲染。所以可以从两方面做修改:一是返回结果的赋值变量上,另一个就是dom节点的渲染层面。
- 给予赋值变量初始值,即定义时menu_items:[ {fullname: ‘’} ]。这么做的好处就是页面节点的渲染不受限于返回结果,静态文案照样会被渲染,动态数据则会在数据更新时被填充。给用户的感觉就是,页面渲染速度不错。但是这种方式也有缺陷,后台返回数据字段不尽相同,要是都这么写那就真是麻烦了。当然如果你使用typescript就没有这种烦恼,menu_items: { [propName: string]: any } = {}就搞定了。
- v-if,控制dom节点的挂载,当且仅当menu_items被赋予返回值时,才开始渲染节点。这么做的好处就是静态和动态文案同步展现在用户面前,不会有文案跳动,数据从无到有的过程。但是,副作用就是页面渲染时间、用户等待时间变长。