文章目录
- 一、Vue3 生命周期概述
- 二、Vue3 组合式API 与选项式API 的对比
- 1. 选项式API 生命周期钩子函数
- 常用的生命周期钩子函数包括:
- 2. 组合式API 的优势
- 组合式API 的主要优势包括:
- 在生命周期管理上的优势
- 三、Vue3 组合式API 生命周期钩子函数
- 1. setup 函数
- 特点和作用:
- 2. onBeforeMount
- 代码示例:
- 使用场景:
- 3. onMounted
- 代码示例:
- 使用场景:
- 4. onBeforeUpdate
- 代码示例:
- 使用场景:
- 5. onUpdated
- 代码示例:
- 使用场景:
- 6. onBeforeUnmount
- 代码示例:
- 使用场景:
- 7. onUnmounted
- 代码示例:
- 使用场景:
- 8. 其他生命周期钩子函数
- 四、生命周期钩子函数的应用实例
- 示例1:数据加载和DOM操作
- 示例2:资源清理
- 示例3:依赖于props的异步操作
一、Vue3 生命周期概述
Vue3 的生命周期钩子函数可以帮助开发者在组件的不同阶段执行特定的逻辑,以便更好地管理和优化应用。
Vue的组件实例从创建到销毁会经历一系列的生命周期阶段,每个阶段都有相应的钩子函数,开发者可以利用这些钩子函数在组件的生命周期中的关键时刻注入自己的代码。
-
初始化阶段:在这个阶段,Vue会进行事件和生命周期的初始化。对于组合式 API,这个阶段主要与
setup
函数的调用相关。 -
模板编译阶段:将模板编译成渲染函数的阶段。这个阶段在使用组合式 API 时通常不需要直接操作。
-
挂载阶段:组件被挂载到 DOM 上。在组合式 API 中,对应的生命周期钩子函数是
onBeforeMount
和onMounted
。 -
更新阶段:当组件的数据变化时,组件会重新渲染。在这个阶段,可以利用
onBeforeUpdate
和onUpdated
钩子函数执行特定逻辑。 -
卸载阶段:组件从 DOM 中移除。这个阶段的钩子函数是
onBeforeUnmount
和onUnmounted
。
在 Vue3 的组合式 API 中,所有这些生命周期钩子函数都可以直接在setup
函数中使用,这提供了一种更灵活、更函数式的方式来组织和复用组件逻辑。通过这种方式,Vue3 不仅保持了其响应式系统的核心优势,还在组件逻辑复用方面做出了革新。
二、Vue3 组合式API 与选项式API 的对比
Vue.js 提供了两种主要的API风格来编写组件:选项式 API 和组合式 API。
1. 选项式API 生命周期钩子函数
选项式 API 是 Vue2.x 引入的,Vue3 亦保留了这种风格。在选项式 API 中,组件的逻辑是通过一个包含各种属性的对象来组织的,其中包括数据、方法、生命周期钩子等。
常用的生命周期钩子函数包括:
beforeCreate
:在实例初始化之后,数据观察和事件/侦听器配置之前被调用。created
:在实例创建完成后被立即调用,此时数据观察、属性和方法的运算、事件/侦听器的回调已经设置好了。beforeMount
:在挂载开始之前被调用,相关的render
函数首次被调用。mounted
:在实例被挂载后调用,此时可以访问到 DOM。beforeUpdate
:在数据变化导致的虚拟DOM重新渲染和打补丁之前调用。updated
:在数据更改导致的虚拟DOM重新渲染和打补丁之后调用。beforeUnmount
(Vue3 新增):在卸载组件实例之前调用。unmounted
(Vue3 新增):在卸载组件实例之后调用。
这些生命周期钩子提供了在组件不同阶段执行代码的机会,让开发者可以有效地管理组件的状态和行为。
2. 组合式API 的优势
Vue3 引入了组合式 API 作为一个全新的编写组件的方式,旨在解决 Vue2.x 在组件复用和逻辑组织方面的一些限制。
组合式API 的主要优势包括:
- 更好的逻辑组织和复用:组合式 API 通过
setup
函数和其他 Composition API 函数(如reactive
,computed
,watch
)允许开发者更自然地提取和重用逻辑代码,而不是将逻辑分散在选项式 API 的不同选项中。 - 更清晰的代码结构:组合式 API 使得相关功能的代码更加集中,有助于提高代码的可读性和维护性。
- 对 TypeScript 的更好支持:组合式 API 与 TypeScript 配合得更紧密,提供了更好的类型推导和类型检查,使得开发大型应用时代码更健壮。
- 更细粒度的代码分割:通过使用组合式 API,开发者可以更灵活地控制组件的各个方面,比如状态的声明、副作用的执行等,从而更精细地优化组件的行为和性能。
在生命周期管理上的优势
组合式 API 中,生命周期钩子也被作为函数(如 onMounted
, onUpdated
)提供,可以直接在 setup
函数内部使用。这种方式使得生命周期钩子的调用更加直观和灵活,可以更紧密地与组件的其他逻辑结合,提高了代码的组织性和可读性。此外,它也让跨组件的逻辑复用变得更加简单,可以将生命周期钩子和相关逻辑一起封装和复用。
三、Vue3 组合式API 生命周期钩子函数
1. setup 函数
setup
函数是 Vue3 组合式 API 中最重要的一个新概念。它在组件创建之初就被调用,用于替代 Vue2 中的 data
, computed
, methods
, watch
, 以及生命周期钩子函数的部分功能。
特点和作用:
setup
函数执行时,组件的 props 和 context(包括 slots 和 emits)已经被初始化。- 该函数返回的对象中的属性和方法将被暴露给组件的模板。
setup
函数是响应式的,可以使用reactive
,ref
等 API 在其中创建和管理状态。
2. onBeforeMount
在组件被挂载到 DOM 之前调用。
代码示例:
javascript">import { onBeforeMount } from 'vue';export default {setup() {onBeforeMount(() => {console.log('Component is about to be mounted!');});}
}
使用场景:
- 初始化或配置 DOM 相关的操作前的准备工作。
3. onMounted
在组件被挂载到 DOM 之后调用。
代码示例:
javascript">import { onMounted } from 'vue';export default {setup() {onMounted(() => {console.log('Component has been mounted!');});}
}
使用场景:
- 访问或修改 DOM 元素。
- 发送 AJAX 请求获取数据。
4. onBeforeUpdate
在组件更新之前调用。
代码示例:
javascript">import { onBeforeUpdate } from 'vue';export default {setup() {onBeforeUpdate(() => {console.log('Component is about to update!');});}
}
使用场景:
- 在组件更新前执行特定操作,如读取当前 DOM 状态。
5. onUpdated
在组件更新之后调用。
代码示例:
javascript">import { onUpdated } from 'vue';export default {setup() {onUpdated(() => {console.log('Component has been updated!');});}
}
使用场景:
- 更新完成后的 DOM 操作。
- 更新完成后的清理工作。
6. onBeforeUnmount
在组件卸载之前调用。
代码示例:
javascript">import { onBeforeUnmount } from 'vue';export default {setup() {onBeforeUnmount(() => {console.log('Component is about to be unmounted!');});}
}
使用场景:
- 清理组件使用的资源,如事件监听器。
7. onUnmounted
在组件卸载之后调用。
代码示例:
javascript">import { onUnmounted } from 'vue';export default {setup() {onUnmounted(() => {console.log('Component has been unmounted!');});}
}
使用场景:
- 完成组件卸载后的最后清理工作。
8. 其他生命周期钩子函数
Vue3 还提供了其他一些生命周期钩子函数,用于特定场景:
onActivated
和onDeactivated
:用于<keep-alive>
缓存的组件激活和停用。onErrorCaptured
:用于捕获组件树中所有子孙组件的错误。onRenderTracked
和onRenderTriggered
:用于调试,追踪和触发渲染。
四、生命周期钩子函数的应用实例
示例1:数据加载和DOM操作
onMounted
钩子函数是获取数据的理想选择,它保证了组件已经被挂载,因此可以安全地访问到 DOM 元素或进行数据请求。
javascript">import { onMounted, ref } from 'vue';
import axios from 'axios';export default {setup() {const posts = ref([]);onMounted(async () => {try {const response = await axios.get('https://api.example.com/posts');posts.value = response.data;} catch (error) {console.error('Failed to fetch posts:', error);}});return { posts };}
}
使用 onMounted
钩子函数发送 AJAX 请求获取数据,并将数据存储在响应式的 posts
变量中。
示例2:资源清理
在组件中注册事件监听器或定时器时,很重要的一点是在组件卸载前清理这些资源,以避免内存泄漏。这可以通过 onUnmounted
钩子函数来实现。
javascript">import { onMounted, onUnmounted, ref } from 'vue';export default {setup() {const isConnected = ref(false);const connect = () => {// 假设这是连接到某个服务的函数isConnected.value = true;};const disconnect = () => {// 断开连接isConnected.value = false;};onMounted(() => {connect();// 假设我们监听 window 的 resize 事件window.addEventListener('resize', connect);});onUnmounted(() => {disconnect();window.removeEventListener('resize', connect);});return { isConnected };}
}
在这个示例中,onMounted
用于注册事件监听器和初始化连接,而 onUnmounted
用于在组件销毁时移除事件监听器和清理资源。
示例3:依赖于props的异步操作
有时需要在组件中根据 props 的变化来执行异步操作,例如根据从父组件传入的用户ID获取用户信息。这种场景下可以使用 watch
与 onMounted
钩子函数结合使用。
javascript">import { watch, onMounted, ref } from 'vue';
import axios from 'axios';export default {props: {userId: Number},setup(props) {const userInfo = ref(null);const fetchUserInfo = async (id) => {try {const response = await axios.get(`https://api.example.com/users/${id}`);userInfo.value = response.data;} catch (error) {console.error('Failed to fetch user info:', error);}};onMounted(() => fetchUserInfo(props.userId));watch(() => props.userId, (newId) => {fetchUserInfo(newId);});return { userInfo };}
}
这个示例展示了如何在组件被挂载时以及 userId
prop 更改时重新获取用户信息。这种方式确保了即使 userId
在组件生命周期内发生变化,用户信息也能保持最新。