Vue生命周期以及父子组件加载顺序
初始化 - beforeCreate & created#
beforeCreate
:初始化 vue 实例。data
methods
等尚未被初始化,无法调用。
created
:vue 实例初始化完成,完成响应式绑定。data
methods
等都已初始化完成,可调用。尚未开始渲染模板。
注意:beforeCreate & created
并没有渲染 DOM,不能够访问 DOM。如果组件在加载的时候需要和后端有交互,如果是需要访问 props
、data
等数据的话,就需要使用 created
钩子函数。
/**
*
* 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')
}
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渲染 。组件创建完成。开始由创建阶段进入运行阶段。
/**
*
* 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
}
// 在挂载开始之前被调用,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#
/**
*
* vue2.6.X源码地址src/core/observer/scheduler.js
* update 的执行时机是在flushSchedulerQueue 函数调用的时候
*
**/
beforeUpdate#
Vue具有响应式原理,即能够监测到数据的变化。当视图层的数据即将被更新前,就会触发这个生命周期,这个阶段主要可以用在得知哪个组件即将发生数据改动,并且可以移除对其绑定的事件监听器。
updated#
此阶段已经重新渲染完成数据更新后的状态。
注意,尽量不要在 updated
中继续修改数据,否则可能会触发死循环。如果要更改官方建议使用computed
或watch
来进行数据更改。
销毁 - 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#
mounted
和 updated
都不会保证所有子组件都挂载完成。如果想等待所有视图都渲染完成,需要使用 $nextTick
。
mounted() {
this.$nextTick(function () {
// 仅在整个视图都被渲染之后才会运行的代码
})
}
VUE3.0 Composition API 生命周期有何不同#
setup
代替了beforeCreate
和created
。- 生命周期换成了函数的形式,如
mounted
->onMounted
。文档 。
import { onUpdated, onMounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('mounted')
})
onUpdated(() => {
console.log('updated')
})
}
}
Axios等请求数据请求放在哪个生命周期合适?#
一般有两个选择:created
和 mounted
,建议选择后者 mounted
。
执行速度
- 从理论上来说,放在
created
确实会快一些 - 但 ajax 是网络请求,其时间是主要的影响因素。从
created
到mounted
是 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人