前面聊了vue生命周期与路由的先后顺序,现在聊聊computed与各生命周期。先聊一下需求背景,我在做一个图表的时候遇到了,我将图表样式封装为一个组件,然后各个地方需要的时候将数据通过props传入到组件自动画图。因为我这个数据会变化,我的方法里面又有比较多的方法了,就像弄到计算属性里面去,这样在data里面也可以少定义一个属性,然后问题就来了。我在子组件里面读取的props竟然是未定义!!这个问题留到后面解释。
上次我们知道了父组件子组件生命周期的关系,同理我在computed当中定义了一个属性
computed:{ test:function(){ return '我是test' } }
然后我在父组件和子组件生命周期当中都打印出来了。当然我们的computed肯定是有一定的逻辑代码才对的,所以我有写下了这样的测试
data:{ a:23, b:32 }, computed:{ test(){ return this.a+this.b; } }
结果与上面一致,那么说明computed的属性是在created之前就已经执行了。
好这个时候回到我们的问题,我在computed里面定义的为什么在子组件props里面未定义呢。
基于上面的结论我在父级打印我的test发现未定义,那么这个时候子组件的未定义就可以理解了。先贴上我的代码吧
computed:{ test(){ this.ajax.get('url').then((res)=>{ return res.data; }) } }
相信很多人已经明白了,我这是一个异步操作,然而computed在beforeCreate的时候就已经执行了。这个时候我的test相当于没有东西,当然是未定义了。所以导致我整个结构崩盘。
后来我的做法
在data里面定义好test,然后在方法里面建一个_test方法获取数据以后去修改test。然后在子组件的watch里面定义一个监听,监听这个test,test变化就绘图。
其实在computed里面我也尝试过用watch去监听,然后发现问题。computed里面的属性是没有直接的双向数据绑定的。我在<input v-model='test'>直接修改是没用的,只能修改它依赖的data属性。官方也解释了计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。
总结computed是严重依赖data属性的,如果computed里面没有依赖data里面的属性,那就不要用computed了,真心没用后面都没办法去修改。
写的好像有些乱啊,反正我看了,不用吃枪吃毒了。