开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情
Vue2 生命周期钩子
Vue2生命周期钩子是通过在组件实例化时自动调用的特定函数来访问生命周期的。这些函数在特定时间点执行,例如组件创建、挂载、更新和销毁时。通过在组件中定义这些函数,你可以访问组件在特定生命周期阶段发生的事件,以便执行特定的行为或操作。例如,在"created"钩子函数中,通过可以执行初始化任务,而在"beforeDestroy"钩子函数中,则可以清理组件中的未使用资源。
调用的是与特定生命周期阶段相关联的函数。具体来说,Vue.js中常用的生命周期钩子函数包括:
- beforeCreate:在实例被创建之初,数据观测(data observer)和事件机制(event/watcher)都未初始化之前调用。
- created:在实例创建完成后调用,此时已经完成了数据观测(data observer),属性和方法的运算,初始化了事件,但尚未挂载到页面上。
- beforeMount:在挂载开始之前调用,即将开始编译模板,把data里面的数据和模板生成html结构。
- mounted:在挂载完成之后调用,此时组件已经被挂载到页面上,DOM节点也已经插入页面中。
- beforeUpdate:在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子函数中进一步地更改数据,但不推荐这样做。
- updated:在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用,组件DOM已经更新,可以执行依赖于DOM的操作。
- beforeDestroy:在实例销毁之前调用,此时实例仍然完全可用,可以执行一些清理操作。
- destroyed:在实例销毁之后调用,此时组件已经被销毁,数据和事件监听都已经被解绑,不能再调用实例中的任何方法。
Vue3 生命周期钩子
在Vue 3中,生命周期钩子函数名称和调用时机与Vue 2有所不同,主要区别在于Vue 3使用了新的Composition API。下面是Vue 3中常用的生命周期钩子函数:
- onBeforeMount:在挂载开始之前调用。
- onMounted:在挂载完成之后调用。
- onBeforeUpdate:在数据更新之前调用。
- onUpdated:在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。
- onBeforeUnmount:在实例销毁之前调用,此时实例仍然完全可用,可以执行一些清理操作。
- onUnmounted:在实例销毁之后调用,此时组件已经被销毁,数据和事件监听都已经被解绑,不能再调用实例中的任何方法。
- onErrorCaptured:在捕获一个来自子孙组件的错误时被调用,它可以返回 false 以阻止错误继续向上传播。此钩子函数在Vue 2中也有,但在Vue 3中被重命名为"onErrorCaptured"。
除了以上这些生命周期钩子函数,Vue 3还引入了一些新的API,如setup函数,用于代替Vue 2中的created和beforeCreate钩子函数,并且更加灵活,具有更好的逻辑组织能力。
Vue3的生命周期钩子函数又是如何访问组件生命周期的呢?
在Vue 3中,生命周期钩子函数仍然是通过在组件实例化时自动调用的特定函数来访问组件生命周期的。这些函数在特定时间点执行,例如组件创建、挂载、更新和销毁时,与Vue 2的生命周期钩子函数类似。不同的是,在Vue 3中,生命周期钩子函数不再是组件实例的方法,而是在组件选项对象中作为属性进行声明,以便更好地使用Composition API。
例如,在Vue 3中,可以通过以下方式声明一个组件:
import { defineComponent } from 'vue'
export default defineComponent({
// 在setup函数中定义组件的属性和方法
setup() {
// 在onMounted钩子函数中访问组件的生命周期
onMounted(() => {
console.log('组件挂载完成')
})
onBeforeUnmount(() => {
console.log('组件即将销毁')
})
// 返回模板中需要使用的数据和方法
return {
message: 'Hello, Vue 3!'
}
}
})
在这个例子中,我们通过defineComponent函数声明了一个组件,其中onMounted和onBeforeUnmount生命周期钩子函数都在setup函数中进行了声明,以便访问组件的生命周期。同时,我们也在setup函数中定义了message属性,并在return语句中返回了它,以便在模板中使用。
通过这种方式,我们可以更加方便地使用Composition API,同时也可以方便地访问组件的生命周期。
源码层面解析
根据上一案例,当Vue 3的组件实例化时,会通过createComponentInstance函数创建一个组件实例对象,并在其中初始化一些属性和方法,包括组件选项、组件ID、生命周期函数等等。其中,生命周期函数是通过将组件选项对象中的生命周期钩子函数属性绑定到组件实例对象上来实现的。
在createComponentInstance函数中,Vue 3会将组件选项对象中的所有生命周期钩子函数属性都进行遍历,通过proxy函数将这些属性绑定到组件实例对象上。例如,在Vue 3中,onMounted生命周期钩子函数是通过以下方式进行定义和绑定的:
const onMounted = (hook: Function, target: ComponentInternalInstance | null = currentInstance) => {
if (!target) {
warn(`onMounted() is called when there is no active component instance to be associated with. ` +
`Lifecycle injection APIs can only be used during execution of setup().`)
return
}
target.update += hook
}
这里的onMounted函数接收两个参数,一个是需要绑定的生命周期钩子函数,另一个是组件实例对象。在函数内部,会将生命周期钩子函数添加到组件实例对象的update属性中,这个属性在组件更新时会被调用。
除了在createComponentInstance函数中进行绑定,Vue 3还通过invokeDirectiveHook和callWithAsyncErrorHandling等函数,在组件生命周期中的不同阶段调用绑定的生命周期钩子函数,实现了对组件生命周期的访问。这些函数通过使用Composition API提供的provide和inject函数,将组件实例对象传递给生命周期钩子函数,以便进行操作。
综上,Vue 3中的生命周期钩子函数是通过在组件实例对象上绑定生命周期函数属性,并在组件生命周期中的不同阶段调用这些属性上的生命周期钩子函数,来访问组件生命周期的。同时,Vue 3也使用了Composition API提供的函数,将组件实例对象传递给生命周期钩子函数,以便进行操作。