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 文件一致,但需要注意的是生命周期函数的执行时机和异步操作的处理方式。这种设计使得组件的逻辑更加清晰和简洁。