Vue3 script setup 語法糖,就問你甜不甜
theme: orange highlight: railscasts
script setup 語法糖
組合式 API:setup()
基本使用
Vue 3 的 Composition API 系列裡,推出了一個全新的 setup
函式,它是一個元件選項,在建立元件之前執行,一旦 props 被解析,並作為組合式 API 的入口點。
setup
選項是一個接收 props
和 context
的函式,我們參考文件進行討論。此外,我們將 setup
返回的所有內容都暴露給元件的其餘部分 (計算屬性、方法、生命週期鉤子等等) 以及元件的模板。
```
```
新的 setup
選項是在元件建立之前, props
被解析之後執行,是組合式 API 的入口。
注意:
在setup
中你應該避免使用this
,因為它不會找到元件例項。setup
的呼叫發生在data
property、computed
property 或methods
被解析之前,所以它們無法>在setup
中被獲取。在添加了setup的script標籤中,我們不必宣告和方法,這種寫法會自動將所有頂級變數、函式,均會自動暴露給模板(template)使用
這裡強調一句 “暴露給模板,跟暴露給外部不是一回事”
TIP:
說的通俗一點,就是在使用 Vue 3 生命週期的情況下,整個元件相關的業務程式碼,都可以放在 setup
裡執行。
因為在 setup
之後,其他的生命週期才會被啟用,我們對比一下Vue2的Vue3生命週期的變化
元件生命週期
關於 Vue 生命週期的變化,可以從下表直觀地瞭解:
| Vue 2 生命週期 | Vue 3 生命週期 | 執行時間說明 | | ------------- | --------------- | --------------------- | | beforeCreate | setup | 元件建立前執行 | | created | setup | 元件建立後執行 | | beforeMount | onBeforeMount | 元件掛載到節點上之前執行 | | mounted | onMounted | 元件掛載完成後執行 | | beforeUpdate | onBeforeUpdate | 元件更新之前執行 | | updated | onUpdated | 元件更新完成之後執行 | | beforeDestroy | onBeforeUnmount | 元件解除安裝之前執行 | | destroyed | onUnmounted | 元件解除安裝完成後執行 | | errorCaptured | onErrorCaptured | 當捕獲一個來自子孫元件的異常時啟用鉤子函式 |
可以看到 Vue 2 生命週期裡的 beforeCreate
和 created
,在 Vue 3 裡已被 setup
替代。
script setup 語法糖
它是 Vue3 的一個新語法糖,在 setup
函式中。所有 ES 模組匯出都被認為是暴露給上下文的值,幷包含在 setup() 返回物件中。相對於之前的寫法,使用後,語法也變得更簡單。
自動註冊屬性和方法無需返回,直接使用
1.<script setup>
語法糖並不是新增的功能模組,它只是簡化了以往的組合API(compositionApi)的必須返回(return)的寫法,並且有更好的執行時效能。
2.在 setup 函式中:所有 ES 模組匯出都被認為是暴露給上下文的值,幷包含在 setup() 返回物件中。相對於之前的寫法,使用後,語法也變得更簡單。
你不必擔心setup語法糖的學習成本,他是組合式API的簡化,並沒有新增的知識點。你只需要瞭解一些用法和細微的不同之處,甚至比之前寫setup()還要順手!
使用方式也很簡單,只需要在 script 標籤加上 setup 關鍵字即可 ```
```
元件核心 API 的使用
元件自動註冊
在 script setup 中,引入的元件可以直接使用,無需再通過components進行註冊,並且無法指定當前元件的名字,它會自動以檔名為主,也就是不用再寫name屬性了。
示例: ```
```
定義元件的 props
defineProps ----> [用來接收父元件傳來的 props] 程式碼示列
:
通過defineProps
指定當前 props 型別,獲得上下文的props物件。
示例:
```
```
定義 emit
defineEmit ----> [子元件向父元件事件傳遞]
使用defineEmit
定義當前元件含有的事件,並通過返回的上下文去執行 emit。
程式碼示列: ```
```
父子元件通訊
defineProps 用來接收父元件傳來的 props ; defineEmits 用來宣告觸發的事件。
``` //父元件
//子元件
```
子元件通過 defineProps 接收父元件傳過來的資料,子元件通過 defineEmits 定義事件傳送資訊給父元件
useSlots()
和 useAttrs()
獲取 slots 和 attrs
注:useContext API 被棄用,取而代之的是更加細分的 api。
可以通過useContext
從上下文中獲取 slots 和 attrs。不過提案在正式通過後,廢除了這個語法,被拆分成了useAttrs
和useSlots
。
useAttrs
:見名知意,這是用來獲取 attrs 資料,但是這和 vue2 不同,裡面包含了class
、屬性
、方法
。
```
// 新
```
defineExpose API
defineExpose ----> [元件暴露出自己的屬性]
傳統的寫法,我們可以在父元件中,通過 ref 例項的方式去訪問子元件的內容,但在 script setup 中,該方法就不能用了,setup 相當於是一個閉包,除了內部的 template
模板,誰都不能訪問內部的資料和方法。
<script setup>
的元件預設不會對外部暴露任何內部宣告的屬性。
如果有部分屬性要暴露出去,可以使用defineExpose
注意:目前發現
defineExpose
暴露出去的屬性以及方法都是unknown
型別,如果有修正型別的方法,歡迎評論區補充。
如果需要對外暴露 setup 中的資料和方法,需要使用 defineExpose API。示例:
``` //子元件
//父元件
```
定義響應變數、函式、監聽、計算屬性computed
```
```
watchEffect和watch區別
1、watch是惰性執行,也就是隻有監聽的值發生變化的時候才會執行,但是watchEffect不同,每次程式碼載入watchEffect都會執行(忽略watch第三個引數的配置,如果修改配置項也可以實現立即執行)
2、watch需要傳遞監聽的物件,watchEffect不需要
3、watch只能監聽響應式資料:ref定義的屬性和reactive定義的物件,如果直接監聽reactive定義物件中的屬性是不允許的,除非使用函式轉換一下
4、watchEffect如果監聽reactive定義的物件是不起作用的,只能監聽物件中的屬性。
reactive
返回一個物件的響應式代理。
```
```
使用ref也能達到我們預期的'counter',並且在模板中,vue進行了處理,我們可以直接使用counter而不用寫counter.value.
ref和reactive的關係:
ref是一個{value:'xxxx'}的結構,value是一個reactive物件
ref 暴露變數到模板
曾經的提案中,如果需要暴露變數到模板,需要在變數前加入export宣告:
export const count = ref(0)
不過在新版的提案中,無需export宣告,編譯器會自動尋找模板中使用的變數,只需像下面這樣簡單的宣告,即可在模板中使用該變數
```
```
其他 Hook Api
useCSSModule
:CSS Modules 是一種 CSS 的模組化和組合系統。vue-loader 整合 CSS Modules,可以作為模擬 scoped CSS。允許在單個檔案元件的setup
中訪問CSS模組。此 api 本人用的比較少,不過多做介紹。useCssVars
: 此 api 暫時資料比較少。介紹v-bind in styles
時提到過。useTransitionState
: 此 api 暫時資料比較少。useSSRContext
: 此 api 暫時資料比較少。
支援 async await 非同步
注意在vue3的原始碼中,setup執行完畢,函式 getCurrentInstance 內部的有個值會釋放對 currentInstance 的引用,await 語句會導致後續程式碼進入非同步執行的情況。所以上述例子中最後一個 getCurrentInstance() 會返回 null,建議使用變數儲存第一個 getCurrentInstance() 返回的引用.
```
```
<script setup>
中可以使用頂層 await
。結果程式碼會被編譯成 async setup()
:
```
```
另外,await 的表示式會自動編譯成在 await
之後保留當前元件例項上下文的格式。
注意
async setup()
必須與Suspense
組合使用,Suspense
目前還是處於實驗階段的特性。我們打算在將來的某個釋出版本中開發完成並提供文件 - 如果你現在感興趣,可以參照 tests 看它是如何工作的。
定義元件其他配置
配置項的缺失,有時候我們需要更改元件選項,在setup
中我們目前是無法做到的。我們需要在上方
再引入一個 script
,在上方寫入對應的 export
即可,需要單開一個 script。
<script setup>
可以和普通的 <script>
一起使用。普通的 <script>
在有這些需要的情況下或許會被使用到:
- 無法在
<script setup>
宣告的選項,例如inheritAttrs
或通過外掛啟用的自定義的選項。 - 宣告命名匯出。
- 執行副作用或者建立只需要執行一次的物件。
在script setup 外使用export default,其內容會被處理後放入原元件宣告欄位。
```
注意:Vue 3 SFC 一般會自動從元件的檔名推斷出元件的 name。在大多數情況下,不需要明確的 name 宣告。唯一需要的情況是當你需要
<keep-alive>
包含或排除或直接檢查元件的選項時,你需要這個名字。