vue-混合使用 vue2 和 vue3 的生命周期,执行顺序

背景

vue3 默认情况并没有屏蔽 option api,如果混合使用 setup 以及生命周期会发生什么?谁的优先级会更高?

测试

直接上例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<script>
import { computed } from 'vue';
import { onBeforeMount } from 'vue';
import { watch } from 'vue';
import { onUpdated } from 'vue';
import { onBeforeUpdate } from 'vue';
import { onMounted } from 'vue';
import { ref } from 'vue';

export default {
// setup
setup() {
console.log('setup');

// setup 中的数据
const msg = ref('msg in setup');

// 挂载前
onBeforeMount(() => {
console.log('onBeforeMount');
});

// 挂载后
onMounted(() => {
console.log('onMounted');
});

// 更新前
onBeforeUpdate(() => {
console.log('onBeforeUpdate');
});

// 更新后
onUpdated(() => {
console.log('onUpdated');
});

// 点击方法
const handleClick = () => {
msg.value += 1;
console.log('clicked in setup');
};

// setup 中的计算属性
const computedMsg = computed(() => msg.value + ' in setup');

// setup 中的 watch
watch(msg, (newVal) => console.log(newVal + 'watch in setup'));

return { msg, computedMsg, handleClick };
},
data() {
console.log('data');
return {
// data 中的数据
msg: 'msg in data',
};
},
// 创建前
beforeCreate() {
console.log('beforeCreate');
},
// 创建后
created() {
console.log('created');
},
// 挂载前
beforeMounted() {
console.log('beforeMounted');
},
// 挂载后
mounted() {
console.log('mounted');
},
// 更新前
beforeUpdate() {
console.log('beforeUpdate');
},
// 更新后
updated() {
console.log('updated');
},
// 方法
methods: {
handleClick() {
console.log('clicked in methods');
},
},
watch: {
msg(newVal) {
console.log(newVal + 'watch in option');
},
},
};
</script>

<template>
<button @click="handleClick">click</button>
{{ msg }}
</template>

首先可以看到,创建阶段,执行结果是:

  1. setup 最先执行;
  2. 然后是 vue2 中的三个创建周期函数:beforeCreate、data、created;
  3. 接下来是 setup 中的 onBeforeMount、vue3 的 onBeforeMount;
  4. 然后是 setup 中的 onMounted、vue2 中的 mounted;

在这里插入图片描述

接着看方法,点击按钮,触发的是 vue2 的 methods:

在这里插入图片描述

删除后会触发 setup 中的方法:

在这里插入图片描述

同时,从上图可以看到,不管是 setup 中还是 option 中的 watch 都会被执行。

最后把 data 删掉,点击按钮,会发现,组件更新先执行 onBeforeUpdate,然后是 vue2 中的 beforeUpdate,最后是 setup 中的 onUpdated、vue2 中的 updated。

在这里插入图片描述

结论

整体而言,vue3 中的生命周期钩子函数会优先于 vue2 的 option api 执行。

那为什么 data、methods 中相同命名的变量、方法,会展示、绑定到界面,而不是 setup 中的 ref 或者方法呢?

是因为 setup 先执行,然后 data、methods 后执行,后者会覆盖前者。

setup 中为什么没有 beforeCreate 和 created?

setup 最先执行,组件实例已经创建,beforeCreate 和 created 已经没有意义了。