vue 父子组件生命周期 分析以及 vueX 异步存储和读取

场景:

我要在App.vue中读取vuex 中存的某个数据,然后去创建一个socket实例并订阅它。接着我还在某个路由组件中,也订阅这个已经被实例化的socket。

出现的问题:

1. 在App.vue中直接读取vuex时,会出现目标对象能打印出来,但是当你拿对象里的数据时,就拿不到数据的情况。

2. 在App.vue中的mounted钩子中创建一个socket实例并订阅它,然后在子组件订阅它时,会发现socket实例还没创建好。

问题分析及对应的知识点:

问题一原因:

对象(复杂)变量(引用类型)都是对象在内存中的地址值,普通数据变量是实际的值。

当app.vu读取数据和vueX actions 存储数据基本上是同时操作的时候(实际上vueX actions 存储数据在先),

但因为vueX actions是异步操作,我们如果直接打印那个存储对象,其实在打印的那一刻对象是能直接能看到的。但是对象展开的时候,单独去拿对象里面的数据的时候,由于这个异步储存对象的过程实际上是没有完成的,所以那个时候就打印对象里的某个数据的时候,是拿不到它的值的。


解决办法:
1,如果是在html中直接使用:

object1.object1.value


2,如果想在js中使用,那么可以使用setTimeout使其也变成一个异步任务,然后添加相应的延时,就能获取到完全存储到地址中的对象了。我这边测试的是需要1s左右的延时,500ms还不够。
setTimeout(() => {
 console.log(this.object1.object1.value)

 this.subscribeWebSocket()
}, 1000);间隔时间根据根据具体测试的结果去设置。

 

问题二原因:

问题二其实是分情况的。

如果子组件不是异步引入的,就是普通正常引入,那么父子组件的生命周期钩子函数的执行顺序为:

app.vue create

child.vue create

child.vue mounted

app.vue mounted

这种情况,子组件肯定是先跑的,如果你子组件和父组件订阅socket都放在mounted中,那子组件订阅socket时肯定会有问题,因为这个时候,socket实例还没创建好。

所以,创建socket实例肯定不能放到mounted中,可以放在create中。如果因为一些其他的原因不能放到create中,那就要想一些其他的办法 了。

这里我们着重讨论第二种情况,我们现在基本上都是异步懒加载组件的,那么父子组件的生命周期钩子函数的执行顺序是这样:

app.vue create

app.vue mounted

child.vue create

child.vue mounted

这样就不会出现刚刚说的那个问题。但是会有其他的问题,那就是因为我们在app.vue mounted中延时异步获取了vuex 中的数据,所以这里会导致socket实例创建也延时了,这个时候如果子组件mounted不做异步延时,会出现子组件mounted中订阅socket先执行。

所以这个时候的解决办法就是,在子组件的mounted中也得加一个

setTimeout(() => {

this.observeWebSocket()
}, 1000);间隔时间根据根据具体测试的结果去设置, 至少要保证和app.vue中延时的时间一样活着更长。

 

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页