Vue 的生命周期详解

167 阅读4分钟

解答

  • Vue的生命周期到底是什么
  • Vue生命周期的执行顺序
  • 生命周期的每个阶段适合做什么
  • 我们的请求放在哪个生命周期会更合适

[参考文章](juejin.cn/post/703288…)

何为 Vue 的生命周期?

  • 简单来说,即描述一个组件从引入到退出的全过程。
  • 复杂来说,即一个组件从【创建】开始经历了【数据初始化】,【挂载】,【更新】等步骤后,最后被【销毁】。

Vue 生命周期的执行顺序?

三大阶段,八小阶段。

  • 挂载阶段

    • beforeCreate
    • created
    • beforeMounted
    • mounted
  • 更新阶段

    • beforeUpdate
    • updated
  • 销毁阶段

    • beforeDestroy
    • destroyed

执行顺序如下:

官方文档介绍

生命周期执行过程翻译如下:

挂载阶段

  • beforeCreate:创建前的状态,什么信息都木有
  • created:创建完成,可以拿到数据 data,但 DOM 元素获取不到。【created 已经将数据加载进来了,已经为 Vue 实例开辟了内存空间】
  • beforeMount:挂载前的状态,将虚拟 DOM 转化成真实 DOM 的过程
  • mounted:挂载结束,意味着虚拟 DOM 已经挂载在真实的元素上,可以拿到 DOM 元素啦。同时可以利用 console.dir 去打印一些需要的元素属性。

更新阶段

  • beforeUpdate:页面元素更新前的状态
  • updated:页面元素更新完成的状态

销毁阶段

  • beforeDestory:销毁前的状态,在销毁前,我们的元素、data都是如同挂载之后的阶段一样,都是可以打印出来的。
  • destoryed:销毁完成的状态,元素还是可以打印出来的。
  • beforeDestroy 和 destroyed,都是我们离开这个组件才会被调用的生命周期。

生命周期每个阶段需要干啥?

created

 在Vue实例创建完毕状态,我们可以去访问data、computed、watch、methods上的方法和数据,但现在还没有将虚拟Dom挂载到真实Dom上,所以我们在此时访问不到我们的Dom元素(el属性,ref属性此时都为空)

【我们在此时可以进行一些简单的Ajax,并可以对页面进行初始化之类的操作 】

beforeMounted

它是在挂载之前被调用的,会在此时去找到虚拟Dom,并将其编译成Render

mounted

虚拟Dom已经被挂载到真实Dom上,此时我们可以获取Dom节点,$ref在此时也是可以访问的

【我们在此时可以去获取节点信息,做Ajax请求,对节点做一些操作 】

beforeUpdate

响应式数据更新的时候会被调用,beforeupdate 的阶段虚拟Dom还没更新,所以在此时依旧可以访问现有的 Dom

【我们可以在此时访问现有的Dom,手动移除一些添加的监听事件 】

updated

此时补丁已经打完了,Dom 已经更新完毕,可以执行一些依赖新 Dom 的操作

【但还是不建议在此时进行数据操作,避免进入死循环 】

beforeDestroy

在 Vue 实例销毁之前被调用,在此时我们的实例还未被销毁

【在此时可以做一些操作,比如销毁定时器,解绑全局事件,销毁插件对象等 】

父子组件的生命周期

  • 挂载阶段:

    父组件 beforeMount -> 子组件 created -> 子组件 mounted -> 父组件 mounted

  • 更新阶段:

    父组件 beforeUpdate -> 子组件 beforeUpdate -> 子组件 updated -> 父组件 updated

  • 销毁阶段:

    父组件 beforeDestroy -> 子组件 beforeDestroy -> 子组件 destroyed -> 父组件 destroyed

补充:请求最好放在哪?

一般来说,会有两种回答:createdmounted。 上文已经讲了,这两个回答,前者是数据已经准备好了,后者是连dom也已经加载完成了,那么到底哪个才是正确答案呢?

其实,两个都是可以的,但是mounted会更好。

原因一:因为在 created 阶段中还没有 DOM 元素,接下来要执行 DOM 渲染。若此时进行 Ajax 操作,在 Ajax 结束后会返回数据,我们会将其插入到主线程中去运行,去处理数据。但要知道【在浏览器机制中,渲染线程跟 js 线程是互斥的】,所以【有可能】我们做渲染的同时。另外一边可能要处理 Ajax 返回的数据。此时的渲染【有可能被打断】,在处理完数组后,去进行重新渲染。如果遇到多个 Ajax 请求的话,此时就很糟糕了。

原因二:同时有时候发送请求返回的数据,是需要在回调函数中去执行一些 DOM 操作。但此时的 created 阶段的真实 DOM 还未加载出来。