生命周期
- Vue3官网-生命周期钩子函数;
- 每个Vue组件实例在创建时都需要经历一系列的初始化步骤,比如数据侦听、编译模板、挂载实例到
DOM
,以及在数据改变时更新DOM
。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。最常见的是created
、mounted
、updated
、unmounted
。
一、组合式API
-
🔺
setup
说明:- setup的执行时机:
beforeCreated
钩子之前,自动执行;
- setup中的this指向谁:
undefined
- setup的执行时机:
-
父组件:
html<script setup> import { ref, reactive, computed, onMounted } from 'vue' // TODO 导入组件 import Vue1 from '@/components/23-生命周期/组合式API/1.vue' // TODO 声明变量 let isShow = ref(false) onMounted(() => {}); </script> <template> <h3>App组件</h3> <label> <input type="checkbox" v-model="isShow"> 是否显示子组件 </label> <hr> <Vue1 subTitle="好好学习" v-if="isShow" /> </template>
-
子组件:
html<template> <h4 id="age"> <i>年龄:{{ age }}</i> </h4> <button @click="age = 70">年龄改成70</button> <button @click="age = 30">年龄改成30</button> </template> <script setup> import { ref, reactive, computed, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from "vue"; // TODO 父组件传递的数据 let props = defineProps({ subTitle: { type: String } }) // TODO 声明响应式数据 let age = ref(22); const showMessage = () => { console.log('函数 HELLO') } // TODO 生命周期钩子函数 onBeforeMount(() => {}) onMounted(() => {}) onBeforeUpdate(() => {}) onUpdated(() => {}) onBeforeUnmount(() => {}) onUnmounted(() => {}); </script>
1.1 onBeforeMount
-
组件视图 在浏览器 渲染之前 调用;
-
可访问 :
- 组件实例东西【数据源、函数、计算属性等】;
-
不能访问 :
- 组件视图中的
DOM
元素。
- 组件视图中的
-
示例展示:
html<template> <h4 id="age"> <i>年龄:{{ age }}</i> </h4> <button @click="age = 70">年龄改成70</button> <button @click="age = 30">年龄改成30</button> </template> <script setup> import { ref, reactive, computed, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from "vue"; // TODO 父组件传递的数据 let props = defineProps({ subTitle: { type: String } }) // TODO 声明响应式数据 let age = ref(22); const showMessage = () => { console.log('函数 HELLO') } // TODO 生命周期钩子函数 onBeforeMount(() => { console.log('-----------------------') console.log('onBeforeMount - 组件渲染之前,能访问数据源、计算属性、侦听器、函数等等,但是不能访问DOM元素') console.log(age.value) console.log(props.subTitle) showMessage() console.log(document.getElementById("age")) }) </script>
-
运行效果:
1.2 onMounted
-
组件视图 在浏览器 渲染之后 调用;
-
可访问 :
- 组件实例东西【数据眼、函数、计算属性等】;
- 组件视图中的
DOM
元素。
-
示例展示:
jsonMounted(() => { console.log('-----------------------') console.log('onMounted - 组件视图渲染之后,能访问数据源、计算属性、侦听器、函数、DOM元素等等') console.log(age.value) console.log(props.subTitle) showMessage() console.log(document.getElementById("age")) })
-
运行效果:
1.3 onbBeforeUpdate
-
数据源发生变化 时,组件试图重新 渲染之前 调用;
-
可访问 :
- 组件实例的东西【数据源、函数、计算属性】;
-
注意 :
- 可访问 该组件中在 更新之前的
DOM
元素; - 不能访问 该组件中在 更新之后的
DOM
元素。
- 可访问 该组件中在 更新之前的
-
示例展示:
jsonBeforeUpdate(() => { console.log('-----------------------') console.log('onBeforeUpdate - 数据变化之前,能访问数据源、计算属性、侦听器、函数、视图重新渲染之前的DOM元素等等') console.log(age.value) console.log(props.subTitle) showMessage() console.log(document.getElementById("age").innerHTML) })
-
运行效果:
1.4 onUpdated
-
数据源发生变化 时,组件试图重新 渲染之后 调用;
-
可访问 :
- 组件实例东西【数据源、函数、计算属性等】;;
-
注意 :
- 不能访问 该组件中在 更新之前的
DOM
元素; - 可以访问 该组件中在 更新之后的
DOM
元素。
- 不能访问 该组件中在 更新之前的
-
示例展示:
jsonUpdated(() => { console.log('-----------------------') console.log('onUpdated - 数据变化之后,能访问数据源、计算属性、侦听器、函数、视图重新渲染之后的DOM元素等等') console.log(age.value) console.log(props.subTitle) showMessage() console.log(document.getElementById("age").innerHTML) })
-
运行效果:
1.5 onBeforeUnmount
-
组件实例被 卸载之前 调用;
-
可访问 :
- 组件实例东西【数据源、函数、计算属性】;
- 组件试图中的
DOM
元素。
-
示例代码:
jsonBeforeUnmount(() => { console.log('-----------------------') console.log('onBeforeUnmount - 组件卸载之前,能访问数据源、计算属性、侦听器、函数、视图DOM元素等等') console.log(age.value) console.log(props.subTitle) showMessage() console.log(document.getElementById("age")) })
-
运行效果:
1.6 onUnmounted
-
组件实例被 卸载之后 调用;
-
可访问 :
- 组件实例东西【数据源、函数、计算属性】;
-
不能访问 :
- 组件试图中的
DOM
元素;
- 组件试图中的
-
一般在这个生命周期函数里,我们可以手动清理一些副作用,例如计时器、
DOM
事件监听器或者与服务器的连接。 -
示例代码:
jsonUnmounted(() => { console.log('-----------------------') console.log('onUnmounted - 组件卸载之后,能访问数据源、计算属性、侦听器、函数等等,但是不能视图DOM元素') console.log(age.value) console.log(props.subTitle) showMessage() console.log(document.getElementById("age")) });
-
运行效果:
二、 选项式API
2.1 beforeCreate
-
beforeCreate
选项式 生命周期函数; -
在 组件实例初始化之前调用 【
props
解析已解析、data
和computed
等选项还未处理】; -
能访问 :
- props数据;
-
不能访问 :
- 组件的实例
this
; - 组件中的 data中的数据 和 methods中的方法;
- 组件中的 视图
DOM
元素; - 组件中的 计算属性 等;
- 组件的实例
-
组合式API 中的
setup()
钩子 会在 所有选项式API钩子 之前 调用。 -
示例展示:
-
App.vue
:html<script setup> import { ref, reactive, computed, onMounted } from 'vue' // 组合式API 中,导入组件之后不用注册,直接使用即可 import Vue1 from '@/components/23-生命周期/1.vue' onMounted(() => {}); </script> <template> <h4>App组件</h4> <br> <Vue1></Vue1> </template>
-
子组件:
html<script> export default { props: { subtitle: { default: '不能懈怠!!!' } }, // data 写箭头函数的时候,给 return 的对象 添加小括号 data: () => ({ age: 22 }), methods: { showMessage() { console.log('函数:beforeCreate') } }, /** * 组件实例化之前调用 * 能访问: * props中的数据 * 不能访问: * data中的数据、methods中的方法、计算属性、视图DOM元素、组件实例this */ beforeCreate() { console.log('beforeCreate, 组件实例化之前') console.log('能够访问props', this.$props.subtitle) console.log('不能访问 data中的数据、方法、计算属性等', this.age) console.log('不能访问 视图元素', document.getElementById('day')) this.showMessage() } } </script> <template> <h4 id="day">每天进步一点点</h4> </template>
-
-
运行展示:
2.2 created
-
created
选项式 生命周期函数; -
在 组件实例化 成功后 调用;
-
可访问 :
- 组件的 实例
this
; - 组件中的 data中的数据 和 函数;
- 组件中的 计算属性;
- 还有 自定义属性(props) 等;
- 组件的 实例
-
不能访问 :
- 组件中的 视图DOM元素。
-
示例展示:
-
子组件代码:
jsocmputed: { ageAdd() { retutn this.age++ } }, /** * 组件 实例化 成功 之后 调用 * 能访问: * data数据、methods方法、props数据、组件实例this、计算属性 * 不能访问: * 视图 DOM 元素 */ created() { console.log('-------------------------------') console.log('created 组件 实例化 成功 之后 调用') console.log('能够访问props:', this.$props.subtitle) console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd) console.log('不能访问 视图元素:', document.getElementById('day')) this.showMessage() },
-
-
运行展示:
2.3 beforeMount
-
组件视图在浏览器 渲染之前 调用;
-
可访问 :
- 组件实例东西【数据源、函数、计算属性等】;
-
不能访问 :
- 组件视图中的
DOM
元素。
- 组件视图中的
-
示例展示:
js/** * 组件视图 渲染之前 调用 * 能访问: * data数据、methods方法、计算属性、组件实例this、props数据等 * 不能访问: * 视图DOM元素 */ beforeMount() { console.log('-------------------------------') console.log('beforeMount 组件视图 渲染之前 调用') console.log('能够访问props:', this.$props.subtitle) console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd) this.showMessage() console.log('不能访问 视图元素:', document.getElementById('day')) }
-
运行效果:
2.4 mounted
-
组件视图在浏览器 渲染之后 调用;
-
可访问 :
- 组件实例东西【数据眼、函数、计算属性等】;
- 组件视图中的
DOM
元素。
-
示例展示:
html<script> /** * 组件视图 渲染之后 调用 * 能访问: * 组件实例this、data数据、methods方法、计算属性、侦听器、视图DOM元素 */ mounted() { console.log('-------------------------------') console.log('mounted 组件视图 渲染之后 调用') console.log('能够访问props:', this.$props.subtitle) console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd) this.showMessage() console.log('能访问 视图元素:', document.getElementById('day')) }, </script> <template> <h4 id="day">每天进步一点点</h4> <h5 id="age">{{ age }}</h5> <button @click="age = 23">数据源发生改变,视图更新之前</button> <button @click="age = 24">数据源发生改变,视图更新之后</button> </template>
-
运行效果:
2.5 beforeUpdate
- 数据源发生变化 时,组件试图重新 渲染之前 调用;
- 可访问 :
- 组件实例的东西【数据源、函数、计算属性】;
- 注意 :
- 可访问 该组件中在 更新之前的
DOM
元素; - 不能访问 该组件中在 更新之后的
DOM
元素。
- 可访问 该组件中在 更新之前的
- 示例代码:看下一小节(8.6),放在一起做对比,效果更明显;
2.6 updated
-
数据源发生变化 时,组件试图重新 渲染之后 调用;
-
可访问 :
- 组件实例东西【数据源、函数、计算属性等】;;
-
注意 :
- 不能访问 该组件中在 更新之前的
DOM
元素; - 可以访问 该组件中在 更新之后的
DOM
元素。
- 不能访问 该组件中在 更新之前的
-
示例代码:
html<script> export default { /** * 数据源发生改变,视图重新渲染之前 调用 * 能访问: * 组件实例this、data数据、methods方法、计算属性、侦听器、数据更新之前的视图DOM元素 * 不能访问: * 数据更新之后的DOM */ beforeUpdate() { console.log('-------------------------------') console.log('beforeUpdate 数据源发生改变,视图重新渲染之前 调用') console.log('能够访问props:', this.$props.subtitle) console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd) this.showMessage() console.log('能访问:数据源发生改变,视图更新之前的DOM元素:', document.getElementById('age').innerHTML) }, /** * 数据源发生改变,视图重新渲染之后 * 能访问: * 组件实例this、data数据、methods方法、计算属性、侦听器、数据更新之后的视图DOM元素 * 不能访问: * 数据更新之前的DOM元素 */ updated() { console.log('-------------------------------') console.log('updated 数据源发生改变,视图重新渲染之后 调用') console.log('能够访问props:', this.$props.subtitle) console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd) this.showMessage() console.log('能访问:数据源发生改变,视图更新之后的DOM元素:', document.getElementById('age').innerHTML) } } </script> <template> <h4 id="day">每天进步一点点</h4> <h5 id="age">{{ age }}</h5> <button @click="age = 23">数据源发生改变,视图更新之前</button> <button @click="age = 24">数据源发生改变,视图更新之后</button> </template>
-
运行效果:
2.7 beforeUmount
- 组件实例被 卸载之前 调用;
- 可访问 :
- 组件实例东西【数据源、函数、计算属性】;
- 组件试图中的
DOM
元素。
- 示例代码:与 8.8 代码放在一起,好对比。
2.8 unmounted
-
组件实例被 卸载之后 调用;
-
可访问 :
- 组件实例东西【数据源、函数、计算属性】;
-
不能访问 :
- 组件试图中的
DOM
元素;
- 组件试图中的
-
一般在这个生命周期函数里,我们可以手动清理一些副作用,例如计时器、
DOM
事件监听器或者与服务器的连接。 -
示例展示:
-
目标文件
App.vue
(父组件):html<script> import Vue1 from '@/components/23-生命周期/1.vue' export default { components: { Vue1 }, data: () => ({ checked: false }) } </script> <template> <h4>App组件</h4> <label> 是否显示子组件 <input type="checkbox" v-model="checked"> </label> <br> <Vue1 v-if="checked"></Vue1> </template>
-
目标文件:
1.vue
(子组件):js/** * 组件实例 被卸载之前 调用 * 能访问:组件实例、data数据、methods方法、计算属性、侦听器、props等等 * 不能访问: * */ beforeUnmount() { console.log('-------------------------------') console.log('beforeUnmount 组件实例 被卸载之前 调用') console.log('能够访问props:', this.$props.subtitle) console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd) this.showMessage() console.log('能访问:DOM元素:', document.getElementById('age').innerHTML) }, /** * 在 组件实例 被卸载之后 调用 * 能访问: * props、data数据、methods方法、计算属性、侦听器、组件实例this等等 * 不能访问: * 组件视图中的DOM元素 * */ unmounted() { console.log('-------------------------------') console.log('unmounted 组件实例 被卸载之后 调用') console.log('能够访问props:', this.$props.subtitle) console.log('能访问 data中的数据、方法、计算属性等:', this.age, this, this.showMessage, this.ageAdd) this.showMessage() console.log('能访问:DOM元素:', document.getElementById('age').innerHTML) }
-
-
运行效果:
三、 生命周期总结(选项式+组合式)
3.1 组合式API:
钩子函数 | 调用时机 | 可以访问 | 不能访问 |
---|---|---|---|
onBeforeMount |
组件视图渲染之前 | 数据源、函数、计算属性、侦听器、props 等等 |
组件中的DOM 元素 |
onMounted |
组件视图渲染之后 | 数据源、函数、计算属性、侦听器、props 、DOM 元素等等 |
|
onBeforeUpdate |
数据发生变化,视图重新渲染之前 | 数据源、函数、计算属性、侦听器、props 、视图重新渲染之前的DOM 元素等等 |
视图重新渲染之后的DOM 元素 |
onUpdated |
数据源发生变化,视图重新渲染之后 | 数据源、函数、计算属性、侦听器、props 、视图重新渲染之后的DOM 元素等等 |
视图重新渲染之前的DOM 元素 |
onBeforeUnmount |
组件卸载之前 | 数据源、函数、计算属性、侦听器、props 、组件的DOM 元素等等 |
|
onUnmounted |
组件卸载之后 | 数据源、函数、计算属性、侦听器、props 等等 |
组件DOM 元素 |
3.2 选项式API
钩子函数 | 调用时机 | 可以访问 | 不能访问 |
---|---|---|---|
beforeCreate |
组件 实例 初始化之前 | 自定义属性(props )等 |
data 数据、methods 方法、组件实例this 、计算属性、侦听器、视图DOM元素 |
🔺created |
组件 实例 初始化 成功之后 | 自定义属性、data 数据、methods 方法、组件实例this 、计算属性、侦听器等 |
视图DOM元素 |
beforeMount |
组件 渲染 之前 | 自定义属性、data 数据、methods 方法、组件实例this 、计算属性、侦听器等 |
视图DOM元素 |
🔺mounted |
组件 渲染成功 之后 | 组件实例this 、data 数据、methods 方法、计算属性、侦听器、视图DOM元素等 |
|
beforeUpdate |
数据发生改变,DOM更新之前 | 组件实例this 、data 数据、methods 方法、计算属性、侦听器、自定义属性(props )、组件更新之前的DOM元素等 |
组件更新之后的DOM元素 |
updated |
数据发生改变,DOM更新之后 | 组件实例this 、data 数据、methods 方法、计算属性、侦听器、自定义属性(props )、组件更新之后的DOM元素等 |
组件更新之前的DOM元素 |
beforeUnmount |
组件实例 被卸载之前 | 组件实例this 、data 数据、methods 方法、计算属性、侦听器、自定义属性(props )、组件视图DOM元素等等 |
|
unmounted |
组件实例 被卸载之后 | 组件实例this 、data 数据、methods 方法、计算属性、侦听器、自定义属性(props )等等 |
组件视图DOM元素 |