Vue生命周期以及父子组件加载顺序

lifecycle

初始化 - beforeCreate & created#

beforeCreate:初始化 vue 实例。data methods 等尚未被初始化,无法调用。

created:vue 实例初始化完成,完成响应式绑定。data methods 等都已初始化完成,可调用。尚未开始渲染模板。

注意:beforeCreate & created 并没有渲染 DOM,不能够访问 DOM。如果组件在加载的时候需要和后端有交互,如果是需要访问 propsdata 等数据的话,就需要使用 created 钩子函数。

Copy
/** * * vue2.6.X源码地址src/core/instance/init.js * beforeCreate 和 created 函数都是在实例化 Vue 的阶段,在 _init 方法中执行的。 * **/ Vue.prototype._init = function (options?: Object) { vm._self = vm initLifecycle(vm) // 初始化生命周期相关的属性、相关属性赋值 initEvents(vm) // 初始化事件队列以及监听器 // 通过defineProperty的set去notify()通知subscribers有值被修改,并执行watchers的update函数 // attrs/$listeners的响应化 initRender(vm) callHook(vm, 'beforeCreate') initInjections(vm) // resolve injections before data/props initState(vm) // initState 的作用是初始化 props、data、methods、watch、computed 等属性 initProvide(vm) // resolve provide after data/props callHook(vm, 'created') }
Copy
beforeCreate() { this.$data // undefined this.$el // undefined this.$computed // undefined this.$methods // undefined } created() { this.$data // {__ob__: Observer} this.$el // undefined this.$computed // 可以访问到计算属性 this.$methods // 可以访问到methods中的方法 }

#

挂载 - beforeMount & mounted#

beforeMount:编译模板,调用 render 函数生成虚拟 V-Dom 。但还没有开始渲染真实Dom。

mounted:完成DOM渲染 。组件创建完成。开始由创建阶段进入运行阶段。

Copy
/** * * vue2.6.X源码地址src/core/instance/lifecycle.js * beforeMount 钩子函数发生在 mount,也就是 DOM 挂载之前,它的调用时机是在 mountComponent 函数中 * **/ export function mountComponent ( vm: Component, el: ?Element, hydrating?: boolean ): Component { vm.$el = el // ... callHook(vm, 'beforeMount') let updateComponent /* istanbul ignore if */ if (process.env.NODE_ENV !== 'production' && config.performance && mark) { updateComponent = () => { const name = vm._name const id = vm._uid const startTag = `vue-perf-start:${id}` const endTag = `vue-perf-end:${id}` mark(startTag) const vnode = vm._render() mark(endTag) measure(`vue ${name} render`, startTag, endTag) mark(startTag) vm._update(vnode, hydrating) mark(endTag) measure(`vue ${name} patch`, startTag, endTag) } } else { updateComponent = () => { vm._update(vm._render(), hydrating) } } // we set this to vm._watcher inside the watcher's constructor // since the watcher's initial patch may call $forceUpdate (e.g. inside child // component's mounted hook), which relies on vm._watcher being already defined new Watcher(vm, updateComponent, noop, { before () { if (vm._isMounted) { callHook(vm, 'beforeUpdate') } } }, true /* isRenderWatcher */) hydrating = false // manually mounted instance, call mounted on self // mounted is called for render-created child components in its inserted hook if (vm.$vnode == null) { vm._isMounted = true callHook(vm, 'mounted') } return vm }
Copy
// 在挂载开始之前被调用,beforeMount之前,会找到对应的template,并编译成render函数。 beforeMount{ this.$data // {__ob__: Observer} this.$el // undefined this.$computed // 可以访问到计算属性 this.$methods // 可以访问到methods中的方法 } // 实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问。 mounted() { this.$data // {__ob__: Observer} this.$el // <div id="app"></div> this.$computed // 可以访问到计算属性 this.$methods // 可以访问到methods中的方法 }

更新 - beforeUpdate & updated#

Copy
/** * * vue2.6.X源码地址src/core/observer/scheduler.js * update 的执行时机是在flushSchedulerQueue 函数调用的时候 * **/

beforeUpdate#

Vue具有响应式原理,即能够监测到数据的变化。当视图层的数据即将被更新前,就会触发这个生命周期,这个阶段主要可以用在得知哪个组件即将发生数据改动,并且可以移除对其绑定的事件监听器。

updated#

此阶段已经重新渲染完成数据更新后的状态。

注意,尽量不要在 updated 中继续修改数据,否则可能会触发死循环。如果要更改官方建议使用computedwatch来进行数据更改。

销毁 - beforeDestroy & destroyed - vue2.0版本#

beforeDestroy#

当组件销毁前会进行的操作,卸载组件实例后调用。实例仍然是完全正常的。移除、解绑一些全局事件、自定义事件,可以在此时操作。

destroyed#

组件被销毁。子组件也已销毁。但是父组件已经渲染在 DOM 上的视图仍然会保留在页面上,只有子组件会完全消失。

销毁 - beforeDestroy & destroyed - vue3.0版本#

beforeUnmount#

当组件销毁前会进行的操作,卸载组件实例后调用。实例仍然是完全正常的。移除、解绑一些全局事件、自定义事件,可以在此时操作。

unmounted#

组件被销毁。子组件也已销毁。但是父组件已经渲染在 DOM 上的视图仍然会保留在页面上,只有子组件会完全消失。

特殊钩子函数 - activated、deactivated - keep-alive组件#

activated:被 keep-alive 缓存的组件激活时调用。

deactivated:被 keep-alive 缓存的组件停用时调用。

如何正确的操作 DOM#

mountedupdated 都不会保证所有子组件都挂载完成。如果想等待所有视图都渲染完成,需要使用 $nextTick

Copy
mounted() { this.$nextTick(function () { // 仅在整个视图都被渲染之后才会运行的代码 }) }

VUE3.0 Composition API 生命周期有何不同#

  • setup 代替了 beforeCreatecreated
  • 生命周期换成了函数的形式,如 mounted -> onMounted文档
Copy
import { onUpdated, onMounted } from 'vue' export default { setup() { onMounted(() => { console.log('mounted') }) onUpdated(() => { console.log('updated') }) } }

Axios等请求数据请求放在哪个生命周期合适?#

一般有两个选择:createdmounted ,建议选择后者 mounted

执行速度

  • 从理论上来说,放在 created 确实会快一些
  • 但 ajax 是网络请求,其时间是主要的影响因素。从 createdmounted 是 JS 执行,速度非常快。
  • 所以,两者在执行速度上不会有肉眼可见的差距

代码的阅读和理解

  • 放在 created 却会带来一些沟通和理解成本,从代码的执行上来看,它会一边执行组件渲染,一边触发网络请求,并行
  • 放在 mounted 就是等待 DOM 渲染完成再执行网络请求,串行,好理解。

所以,综合来看,更建议选择 mounted

Vue父子组件的执行顺序#

加载渲染时#

父组件 beforeCreate
父组件 beforeCreate
父组件 created
父组件 beforeMount
子组件 beforeCreate
子组件 created
子组件 beforeMount
子组件 mounted
父组件 mounted

更新时#

父组件 beforeUpdate
子组件 beforeUpdate
子组件 updated
父组件 updated

销毁时#

父组件 beforeDestroy
子组件 beforeDestroy
子组件 destroyed
父组件 destoryed

参考链接#

Vue.js 生命周期 https://ustbhuangyi.github.io/vue-analysis/v2/components/lifecycle.html#beforeupdate-updated

Vue源码解析 https://blog.csdn.net/qq_46299172/article/details/107657663?spm=1001.2014.3001.5502

Vue生命周期及父子组件生命周期的加载顺序 https://www.cnblogs.com/yyy0926/p/15654272.html

posted @   Scok  阅读(2151)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示
CONTENTS