setup函数中执行顺序
# setup函数中执行顺序
在 Vue 3 的 <script setup> 中,所有的代码都会在组件实例创建之前同步执行。这意味着 <script setup> 中的代码是按顺序执行的。下面介绍在 <script setup> 中,变量声明、函数定义、响应式数据初始化、函数调用、箭头函数和生命周期函数等的执行顺序及其行为。
# 1. 变量声明
在 <script setup> 中,所有变量的声明会按照书写的顺序依次执行。这些变量将在组件创建之前完成初始化。
示例:
<script setup>
// 按顺序执行:声明普通变量
let title = 'Welcome to Vue 3';
// 按顺序执行:声明响应式数据
import { ref } from 'vue';
let message = ref('Hello, Vue 3!');
</script>
2
3
4
5
6
7
8
执行顺序:
title被声明并赋值为'Welcome to Vue 3'。message被声明为一个响应式数据,并赋初值'Hello, Vue 3!'。
# 2. 函数定义
函数定义会按照书写顺序执行,但定义函数时并不会立即执行函数体内容。只有在函数被调用时,函数体内容才会执行。
示例:
<script setup>
// 按顺序执行:定义普通函数
function greet() {
console.log('Hello from greet function');
}
// 按顺序执行:定义箭头函数
const sayHi = () => {
console.log('Hi from sayHi function');
};
</script>
2
3
4
5
6
7
8
9
10
11
执行顺序:
greet函数被定义,但不会立即执行。sayHi箭头函数被定义,但不会立即执行。
# 3. 函数调用
在 <script setup> 中,函数调用会按照代码中出现的顺序执行。被调用的函数会立即执行,并根据函数体内的逻辑进行操作。
示例:
<script setup>
import { ref } from 'vue';
let message = ref('Hello');
// 定义函数
function changeMessage() {
message.value = 'Hello, Vue 3!';
console.log('Message changed to:', message.value);
}
// 按顺序执行:立即调用函数
changeMessage(); // 这个函数会在组件渲染之前执行
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
执行顺序:
message被声明为一个响应式数据。changeMessage函数被定义。changeMessage函数被调用,message.value被修改为'Hello, Vue 3!'并输出到控制台。
# 4. 箭头函数
箭头函数在定义时与普通函数的行为相同,都会按顺序执行其定义,但不会立即执行函数体内容。只有在调用箭头函数时,函数体内容才会执行。
示例:
<script setup>
const logMessage = () => {
console.log('Logging from arrow function');
};
// 按顺序执行:调用箭头函数
logMessage();
</script>
2
3
4
5
6
7
8
执行顺序:
logMessage箭头函数被定义。logMessage被调用,执行函数体内容并输出'Logging from arrow function'到控制台。
# 5. 生命周期函数
生命周期函数(如 onMounted、onUnmounted)是在组件生命周期的特定阶段触发的,因此它们不在常规的代码执行顺序之内。即便你在 <script setup> 中注册了这些函数,它们也不会在代码书写顺序中立即执行,而是会在组件达到相应的生命周期阶段时触发。
onMounted:在组件挂载完成(DOM 被插入页面)后执行。onUnmounted:在组件卸载(从 DOM 中移除)时执行。
示例:
<template>
<div>{{ message }}</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
let message = ref('Hello, Vue 3!');
// 定义一个普通函数
function changeMessage() {
message.value = 'Hello, onMounted!';
}
// 注册生命周期函数
onMounted(() => {
console.log('Component mounted');
changeMessage(); // 在组件挂载后调用
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
执行顺序:
message被声明为一个响应式数据。changeMessage函数被定义。onMounted生命周期函数被注册,但此时不会立即执行。- 当组件挂载完成(即 DOM 被插入页面)后,
onMounted中的逻辑才会执行。
# 6. 生命周期函数的写法
在 Vue 3 中,生命周期函数通过组合式 API 注册。这些生命周期函数不必写成箭头函数,可以使用普通函数的形式。重要的是它们的定义必须在 <script setup> 中进行,并通过组合式 API 的方式来注册。
示例:普通函数和箭头函数的使用
<script setup>
import { onMounted, onUnmounted } from 'vue';
function onMountedCallback() {
console.log('Component has been mounted');
}
const onUnmountedCallback = () => {
console.log('Component has been unmounted');
};
// 使用普通函数注册生命周期函数
onMounted(onMountedCallback);
// 使用箭头函数注册生命周期函数
onUnmounted(onUnmountedCallback);
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
说明:
onMountedCallback是一个普通函数,可以直接传递给onMounted。onUnmountedCallback是一个箭头函数,同样可以传递给onUnmounted。
# 7. 异步函数与 Promise
在 Vue 3 的 <script setup> 中,异步函数的行为与普通的 JavaScript 异步函数相同。当代码执行到异步函数时,它会立即启动异步操作,但不会阻塞后续代码的执行。因此,同步代码会继续执行,异步函数内的代码在异步操作完成后才会继续执行。
示例:
<script setup>
import { ref } from 'vue';
let message = ref('Loading...');
// 定义异步函数
async function fetchData() {
const data = await new Promise(resolve => {
setTimeout(() => resolve('Data loaded'), 2000);
});
message.value = data;
}
// 调用异步函数
fetchData();
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
执行顺序:
fetchData异步函数被调用,输出'fetchData started'。await让出执行权,异步操作开始,但不会阻塞后续代码。console.log('This will run before fetchData completes')被执行并输出。- 异步操作完成后,
message.value被更新为'Data loaded',并输出'fetchData completed'。
总结
- 顺序执行:所有变量声明、函数定义和函数调用都是按代码书写顺序执行的。
- 函数定义:函数在定义时不会立即执行,只有调用时才会执行。
- 生命周期函数:使用组合式 API 的生命周期函数(如
onMounted)会在组件生命周期的特定阶段执行。 - 异步操作:异步函数和
Promise会在异步操作完成后继续执行。
在 <script setup> 中的代码结构与普通 JavaScript 文件一致,但需要注意的是生命周期函数的执行时机和异步操作的处理方式。这种设计使得组件的逻辑更加清晰和简洁。