Vue3的生命周期(组合式写法)
写在最前:与Vue2不同,Vue3要在创建vue实例(app = Vue.createApp(options))并且挂载模板(app.mount(el))之后才会执行生命周期流程,而Vue2则是在创建实例(new Vue())之后就开始执行生命周期流程。
vue3生命周期流程
vue的声明周期一般都是成对出现的,基于setup语法糖,vue3的生命周期大致如下:
- setup,此时创建的是data和method,注意组合式写法中,是不允许把beforeCreate和created写进去的
- onBeforeMount,在组件挂载到节点上之前执行
- onMounted,在组件挂载完成之后执行,该生命周期只执行一次,常见于页面初始化,DOM节点的获取一般在此生命周期获取,在onBeforeMount周期获取不到
- onBeforeUpdate,DOM更新之前执行
- onUpdated,组件更新之后执行
- onBeforeUnmount,组件卸载之前执行
- onUnmount,组件挂载之后执行
vue3中生命周期的使用
vue3比vue2最大的特点或许就是更轻量了,因此生命周期的时候在vue3中是需要引进的。以onMounted为例:
<script setup>
import { onMounted } from 'vue'
onMounted(() => {console.log('onMounted执行')})
</script>
setup注意事项以及组合式的优点
- 使用setup有几个必须注意的点,在选项式的写法中setup执行的时期在beforeCreate之前执行,此时this的值是 undefined,setup只执行一次。
- 组合式是Vue3最显著的特点之一,其最大的优点或许就是提高代码的可读性和可维护性,降低代码的耦合度。
同一个功能的实现,如果我们用选项式开发,如下:
<script>
import { ref } from "vue";
export default {
name: "app",
setup() {
let text_1 = ref("");
let text_2 = ref("");
let clickBtn_1 = function () {
alert(this.text_1);
};
let clickBtn_2 = function () {
alert(this.text_2);
};
return { text_1, text_2, clickBtn_1, clickBtn_2 };
},
beforeCreate() {
this.text_1 = "bbb";
this.text_2 = "aaa";
},
};
</script>
<template>
<div>{{ text_1 }}</div>
<input type="text" v-model="this.text_1" />
<button @click="clickBtn_1">btn1</button>
<div>{{ text_2 }}</div>
<input type="text" v-model="this.text_2" />
<button @click="clickBtn_2">btn2</button>
</template>
<style scoped>
</style>
最大的问题就是,我们原本可以把页面分割成两个不同的功能区,第一个功能区对应text_1数据的渲染和修改,另一个功能区对应text_2的,但是再选项式下我们把这两个数据以及与它们相关的操作都放在了setup里,在代码量多的时候是极难维护的。这时候如果用组合式Api配合自定义的hook使用,能很好地解决这个痛点。代码如下:
// text_1.js
import { reactive, onMounted } from 'vue'
export default function () {
// 待操作的数据以及操作数据的方法
let text_1 = reactive({
content: "",
clickBtn_1: function () {
alert(this.content)
}
})
// 挂载
onMounted(() => {
text_1.content = 'aaa'
})
return text_1
}
// app.vue
<script setup>
import useText_1 from './hook/text_1'
let text_1 = useText_1()
</script>
<template>
<div>{{text_1.content}}</div>
<input type="text" v-model="text_1.content">
<button @click="text_1.clickBtn_1">btn_1</button>
</template>
<style scoped>
</style>
同理,我们只要在text_2.js文件下编写与另一个数据有关的操作即可。这样大大降低了耦合度,提高了代码的可读性和可复用性。最后需要注意的是,在组合式的写法中如果一个同一个生命周期,多次被传递了不同的回调函数,所有被传递的回调函数都会在那个生命周期里依次执行,这并不是覆盖的操作,并非只执行最后一个回调函数,因此配合hook使用组合式写法的时候,每个js文件里面都可以写vue的生命周期,此时回调函数的执行顺序与hook被引入的顺序相同。