21、Vue 3 (2024 版)基础笔记 - 生命周期与应用
掌握 Vue 3 的生命周期非常重要。本篇文章不会讲什么生命周期,只记录代码。但是生命周期的图还是展示一下。
Vue 3 生命周期
Vue 3 有的生命周期有 4 种
以及 8 个
生命周期函数,如下:
- 创建期
- beforeCreate、created
- 挂载期
- beforeMount、mounted
- 更新期
- beforeUpdate、updated
- 销毁期
- beforeUnmount、unmounted
下面通过代码演示一下:
src/App.vue
<template>
<h3>生命周期函数演示</h3>
<p>{{ username }}</p>
<button @click="clickHandler">换一个</button>
</template>
<script setup lang="ts">
// 当使用 setup 语法时, beforeCreate 和 created 不需要
import {
ref,
onMounted,
onUpdated,
onUnmounted,
onBeforeMount,
onBeforeUpdate,
onBeforeUnmount
} from 'vue';
// 使用事件用户演示更新操作
const username = ref<string>("王美丽")
const clickHandler = () => {
username.value = "王丽丽"
}
onBeforeMount(() => {
console.log("beforeMount: 组件即将被挂载到 DOM 中");
})
onMounted(() => {
console.log('mounted: 组件已经被成功挂载到 DOM 中');
// 这里可以执行依赖于 DOM 的操作,如第三方库初始化、DOM 查询、添加事件监听器等
})
onBeforeUpdate(() => {
console.log('beforeUpdate: 组件即将更新');
// 可以在此对比旧的 props/state 和新的 props/state,进行必要的状态同步
})
onUpdated(() => {
console.log('updated: 组件已完成更新,DOM 已同步');
// 这里可以处理组件更新后与 DOM 相关的操作,如重新计算尺寸、更新图表数据等
})
onBeforeUnmount(() => {
console.log('beforeUnmount: 组件即将被卸载');
// 可能做一些清理工作:暂停正在进行的动画、取消网络请求、清理定时器等
})
onUnmounted(() => {
console.log('unmounted: 组件已被卸载,释放资源');
// 这里执行必要的清理工作,如移除事件监听器、取消定时器、解绑外部资源等
})
</script>
Vue 3 生命周期的应用
这里使用生命周期获取 ref 获取 DOM 结构
和 发送网络请求获取数据
。
使用 setup
语法获取 DOM
元素时,需要注意:
-
1、
setup
语法中,无法使用$this
-
2.子组件使用
setup
语法糖时,需要添加defineExpose
方法导出 -
3、vue 3 中, ref 在普通标签上获取真实 DOM 元素为
ref.value
-
4、vue 3 在自定义组件上获取真实 DOM 元素的方法为
childRef.value.$el
使用 ref 获取 DOM 结构
先来看看直接在组件中获取 DOM 元素的用法:
src/App.vue
<template>
<div ref="refDiv">setup 语法中,获取 DOM 元素</div>
</template>
<script setup lang="ts">
import { ref,onMounted} from 'vue';
// 定义一个名为refDiv的响应式变量,类型为Ref<HTMLDivElement | null>
// 初始值设为null,表示在组件挂载之前,refDiv.value为null
// 在组件挂载后,refDiv.value将指向一个HTMLDivElement实例
const refDiv = ref<HTMLDivElement|null>(null)
onMounted(() => {
refDiv.value.style.background = 'lightpink'
// 使用 refDiv.value 获取 DOM 元素
console.log(refDiv.value)
})
</script>
父组件中获取子组件的 ref DOM 元素
1、子组件
src/components/RefDomDemo.vue
<template>
<!-- 1. 显示由username变量控制的文本 -->
<div>{{ username }}</div>
</template>
<script setup lang="ts">
// 2. 导入Vue的ref函数,用于创建响应式变量
import { ref } from 'vue';
// 3. 创建一个名为username的响应式变量,类型为string
// 初始值设为'王美丽'
const username = ref<string>('王美丽');
// 4. 使用defineExpose暴露username变量到父组件
// 这使得父组件可以通过模板插槽props、$refs或$attrs访问到该变量
defineExpose({
username
})
</script>
2、父组件
src/App.vue
<template>
<!-- 1. 引入并渲染子组件 RefDomDemo,同时为其设置 ref="usernameRef" -->
<!-- 这使得父组件可以通过 usernameRef 变量访问到子组件的实例 -->
<RefDomDemo ref="usernameRef"></RefDomDemo>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import RefDomDemo from './components/RefDomDemo.vue';
// 2. 创建一个名为 usernameRef 的响应式变量,类型为Ref<null>
// 初始值设为 null,表示在组件挂载之前,usernameRef.value为null
// 在组件挂载后,usernameRef.value 将指向 RefDomDemo 子组件实例
const usernameRef = ref<null>(null);
onMounted(() => {
usernameRef.value.$el.style.color = 'red';
console.log(usernameRef);
});
</script>
通过生命周期函数获取数据
src/App.vue
<template>
<div>
<ul>
<li v-for="article in articles" :key="article.id">{{ article.title }}</li>
</ul>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
const articles = ref<object[]>([]);
onMounted(() => {
// 模拟网络请求获取数据
const response = [
{id:1, title:"PHP"},
{id:2, title:'Vue 3'}
]
articles.value = response
});
</script>