Vue3 的 setup
語法糖是通過 <script setup>
標簽啟用的特性,它是對 Composition API 的進一步封裝,旨在簡化組件的聲明式寫法,同時保留 Composition API 的邏輯組織能力。以下是其核心概念和原理分析:
一、<script setup>
是什么?
-
語法糖本質
它是 Vue3 編譯器在編譯階段對組件邏輯的語法轉換工具。開發者用更簡潔的語法編寫邏輯,最終會被編譯成標準setup()
函數的返回形式。 -
主要特性
- 自動暴露頂層變量(無需
return
) - 直接使用
await
(自動生成異步包裝) - 組件/指令自動注冊(無需
components
選項) - 支持 TypeScript 類型推導(如
defineProps
)
- 自動暴露頂層變量(無需
二、語法糖的編譯原理
以下是一個代碼轉換示例,展示 <script setup>
如何被編譯為傳統寫法:
原始代碼(語法糖):
<script setup>
import { ref } from 'vue'
import MyComponent from './MyComponent.vue'const count = ref(0)
const increment = () => count.value++
</script>
編譯后代碼:
export default {setup() {const count = ref(0)const increment = () => count.value++// 自動返回所有頂層變量return {count,increment,MyComponent // 自動注冊組件}},components: {MyComponent // 編譯器自動處理組件注冊}
}
三、關鍵技術實現
-
編譯階段轉換
Vue 編譯器(如@vue/compiler-sfc
)會在構建時:- 提取
<script setup>
中的頂層變量 - 自動生成
return
語句暴露這些變量 - 將
import
的組件轉換為components
選項
- 提取
-
響應式綁定
ref
或reactive
變量會被編譯器識別,生成對應的 Proxy 響應式代碼。 -
宏函數處理
如defineProps
、defineEmits
是編譯時的特殊宏,編譯器會將其轉換為標準的 props/emits 聲明:<script setup> const props = defineProps({ msg: String }) const emit = defineEmits(['submit']) </script>
編譯為:
export default {props: { msg: String },emits: ['submit'],setup(props, { emit }) {// ...} }
需要注意的是,Vue從3.5版本開始,已經支持
響應式解構Props
,也就是當在同一個 script setup 塊中的代碼訪問從 defineProps 解構出的變量時,Vue 的編譯器會自動在前面添加props.
。const { foo } = defineProps(['foo'])watchEffect(() => {// 在 3.5 之前僅運行一次// 在 3.5+ 版本中會在 "foo" prop 改變時重新運行console.log(foo)})
編譯為:
const props = defineProps(['foo'])watchEffect(() => {// `foo` 由編譯器轉換為 `props.foo`console.log(props.foo)})
四、優勢與適用場景
特性 | 傳統 setup 函數 | <script setup> |
---|---|---|
代碼量 | 需顯式 return | 自動暴露頂層變量 |
組件注冊 | 需在 components 聲明 | 自動注冊導入的組件 |
異步邏輯 | 需手動包裝異步上下文 | 直接使用 await |
TypeScript 支持 | 需類型斷言 | 自動推導 props/emit 類型 |
適用場景:適用于需要清晰邏輯組織的復雜組件,尤其是需要 TypeScript 強類型支持或大量 Composition API 復用的場景。
五、@vue/compiler-sfc核心解析
@vue/compiler-sfc是Vue官方的單文件(SFC)編譯器,負責將.vue文件解析為標準的JavaScript模塊,它的主要任務包括:
- 分離
<template>
、<script>
、<style>
三大塊 - 處理模版編譯為渲染函數
- 轉換
<script setup>
語法糖 - 處理 CSS 作用域(Scoped CSS)
關鍵功能實現
-
模板編譯
將 HTML-like 模板轉換為 虛擬 DOM 渲染函數:<!-- 輸入 --> <template><div @click="count++">{{ count }}</div> </template>
// 輸出渲染函數 import { createElementVNode as _createElementVNode } from "vue" export function render(_ctx) {return _createElementVNode("div", { onClick: _ctx.increment }, _toDisplayString(_ctx.count)) }
-
<script setup>
轉換
將頂層變量自動注入setup()
返回對象:<script setup> import { ref } from 'vue' const count = ref(0) </script>
// 轉換后 export default {setup() {const count = ref(0)return { count } // 自動注入} }
-
CSS 作用域處理
為 Scoped CSS 添加唯一哈希屬性:<style scoped> .box { color: red; } </style>
.box[data-v-5f8d2c] { color: red; }
與其他工具協作
- 與 Vite:通過
@vitejs/plugin-vue
插件集成,實現開發時熱更新 - 與 Webpack:通過
vue-loader
調用@vue/compiler-sfc
- 與 TypeScript:通過
defineProps
/defineEmits
實現類型推導
SFC在線演練場
訪問Vue SFC Playground直接輸入 Vue SFC 代碼,右側會實時顯示編譯后的 JavaScript 代碼。
六、總結
通過編譯時的智能轉換,<script setup>
在保持邏輯組織能力的同時,大幅減少了樣板代碼,是 Vue3 開發的高效實踐方案。
以上就是對 setup 語法糖的一點點介紹啦^-^