在 Vue3 中,直接寫在 <script setup>...</script>
中的代碼運行時機可以分為以下幾個關鍵階段:
一、執行順序層級
二、具體運行階段
1. 組件實例初始化前
- 執行時機:在 Vue 實例化過程中,早于
beforeCreate
生命周期鉤子 - 典型行為:
<script setup> // 以下代碼會先于 beforeCreate 執行 import { ref } from 'vue' const count = ref(0) // 響應式變量初始化 console.log('ScriptSetup 執行') // 會在此階段輸出 </script>
2. 響應式系統構建
- 依賴收集:所有在
<script setup>
中聲明的ref
/reactive
變量會被立即初始化 - 示例驗證:
<script setup> const message = ref('Hello') console.log(message.value) // 輸出 "Hello" </script>
3. 生命周期鉤子對比
代碼位置 | 執行時機 | 示例 |
---|---|---|
<script setup> | beforeCreate 之前 | 初始化響應式變量、導入模塊 |
setup() 函數 | beforeCreate 之前 | (等同于 <script setup> ) |
onMounted 鉤子 | 組件掛載完成后 | 訪問 DOM 元素 |
created 鉤子 | beforeCreate 之后 | 不能訪問 DOM |
三、異步操作的特殊處理
1. 異步代碼執行時機
<script setup>
// 以下異步代碼會立即執行(在實例化前)
const fetchData = async () => {const res = await fetch('/api/data')data.value = await res.json()
}
fetchData() // 立即發起請求
</script>
2. 與生命周期的關系
- 請求會在
beforeCreate
前發起,但響應處理會在組件掛載后完成 - 典型場景:
<script setup> import { ref, onMounted } from 'vue'const data = ref(null)// 立即執行的異步請求 fetchData().then(res => {data.value = res // 在 mounted 鉤子前可能已賦值 })onMounted(() => {console.log(data.value) // 可能已有值(取決于請求速度) }) </script>
四、與選項式 API 的對比
特性 | <script setup> | 選項式 API (setup() 函數) |
---|---|---|
執行時機 | beforeCreate 前 | beforeCreate 前 |
響應式聲明 | ref /reactive 直接聲明 | 需要返回對象 |
代碼組織 | 更簡潔,無 this 上下文 | 需要 this 訪問實例 |
編譯優化 | Tree-shaking 友好 | 需要手動優化 |
五、關鍵注意事項
1. 不要訪問 DOM
<script setup>
// ? 錯誤:此時 DOM 尚未創建
const element = document.getElementById('app')
</script>
2. 異步數據獲取
<script setup>
// ? 正確:在 setup 階段發起請求
const data = ref(null)fetch('/api/data').then(res => {data.value = res.json()
})
</script>
3. 響應式變量初始化
<script setup>
// ? 正確:響應式變量在實例化前初始化
const count = ref(0)
</script>
六、底層原理
-
編譯階段:
- Vue 編譯器將
<script setup>
轉換為setup()
函數 - 所有頂層代碼被提升到
setup()
最頂部
- Vue 編譯器將
-
運行時階段:
- 在組件實例化流程中,先執行
<script setup>
代碼 - 再依次觸發
beforeCreate
→created
→beforeMount
等生命周期
- 在組件實例化流程中,先執行
總結
- 運行時機:
<script setup>
中的代碼在 組件實例化前 執行(早于beforeCreate
) - 核心特性:
- 響應式變量立即初始化
- 頂級代碼立即執行
- 無法訪問 DOM 元素
- 最佳實踐:
- 用于初始化數據、導入模塊、注冊組合函數
- 異步操作需注意執行順序
- 避免在此階段直接操作 DOM