对于vue生命周期我们还是要先了解清楚,因为不同的生命期用不同的钩子函数,先上图:

vue3 钩子函数获取后端数据_数据


遇到的一个问题

在我的项目中,常用的生命周期钩子函数一直都是mounted,对于大部分情况,都是屡试不爽、捷报频传~

但是在前几天却遭遇了一个意外,我在mounted中获取后台数据并更新data,在template中把data.fullname与一个p元素的innerHTML绑定,这是一个简单到不能再简单,普通到不能更普通的操作,打开浏览器一看,完美!fullname的数据正常显示在p元素中,没有任何问题,可是……咦,控制台怎么报错了?

vue3 钩子函数获取后端数据_vue生命周期钩子函数的正确使用方式_02


报错信息的大致意思是,data是null,无法获取到null的fullname属性,可是数据明明正常显示了呀,而且我们不是从后台请求数据并给data赋值了嘛?

经过一番排查,发现原因有两处:

1.List item

初始化时,给data的值是null

data () {
    return {
      data: null,
  },

vue渲染template的时间在beforeMount之后,mounted之前,所以渲染template时data值为null,故而报错;但是待后台数据请求成功给data赋值后,p元素能监听到数据的变化,然后更新其innerHTML,所以UI看起来是很正常的

解决方案:
所以解决方案是非常简单的,只需要保证渲染template的时候,data已经拿到后台数据就可以了,所以可以把mounted钩子函数修改为beforeMount,或者其他更早被调用的钩子函数:beforeCreated、created等

后来经过验证,上述的解决方案是错误的,因为它只针对同步代码有效果。而ajax请求是异步操作,回调函数的执行时间不能确定,所以即使放在created钩子函数中,也不能保证在mounted之前完成数据的请求……

所以最终的解决方案是,给p标签加一个v-if,待data不为null时再进行渲染,但并不算很优雅。

不知道vue的生命周期钩子函数是否支持promise或者async/await,如果大神们有更好的解决方案,欢迎交流~

总结

1 一点小小的感悟,vue生命周期钩子函数的使用并非一成不变的,要根据不同的应用场景而有所改变,稍微总结一下:

2 beforeCreate:在实例初始化之后,**数据观测(data observer) ** 和 event/watcher事件配置
之前被调用,注意是 之前,此时data、watcher、methods统统滴没有。

这个时候的vue实例还什么都没有,但是$route对象是存在的,可以根据路由信息进行重定向之类的操作。

3 created:在实例已经创建完成之后被调用。在这一步,实例已完成以下配置:数据观测(data observer) ,属性和方法的运算,

4 watch/event 事件回调。然而,挂载阶段还没开始,vue3 钩子函数获取后端数据_数据_03data 可以访问,watcher、events、methods也出现了,若根据后台接口动态改变data和methods的场景下,可以使用。

5 beforeMount:在挂载开始之前被调用,相关的 render 函数
首次被调用。但是render正在执行中,此时DOM还是无法操作的。我打印了此时的vue实例对象,相比于created生命周期,此时只是多了一个$el的属性,然而其值为undefined。

使用场景我上文已经提到了,页面渲染时所需要的数据,应尽量在这之前完成赋值。 mounted:在挂载之后被调用。在这一步 创建vm.vue3 钩子函数获取后端数据_vue生命周期钩子函数的正确使用方式_04el也在文档内” 这句话存疑)此时元素已经渲染完成了,依赖于DOM的代码就放在这里吧~比如监听DOM事件。

6.beforeUpdate:vue3 钩子函数获取后端数据_vue生命周期_05vm.data,这不会触发附加的重渲染过程。 updated:虚拟DOM重新渲染 和打补丁之后被调用。

当这个钩子被调用时,组件DOM的data已经更新,所以你现在可以执行依赖于DOM的操作。但是不要在此时修改data,否则会继续触发beforeUpdate、updated这两个生命周期,进入死循环!

7 .beforeDestroy:实例被销毁之前调用。在这一步,实例仍然完全可用。 实例要被销毁了,赶在被销毁之前搞点事情吧哈哈~

8.destroyed:Vue实例销毁后调用。此时,Vue实例指示的所有东西已经解绑定,所有的事件监听器都已经被移除,所有的子实例也已经被销毁。

这时候能做的事情已经不多了,只能加点儿提示toast之类的东西吧。

注:beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed这几个钩子函数,在服务器端渲染期间不被调用。