詳解vue3.2中setup語法糖<script?lang="ts"?setup>
前言
介紹 Vue 3 引入了 Composition API 作為一種在 Vue 應用程序中處理反應狀態(tài)的新方法。您可以按功能(用戶、API、表單)對代碼進行分組,而不是按功能(數據、計算、方法、監(jiān)視等)組織代碼。這在構建 Vue 應用程序時允許更大的靈活性。我們已經在其他文章中討論過 Composition(如果您還沒有閱讀,請查看它們?。?,但是隨著 Vue 3.2 的發(fā)布,另一個與 Composition 相關的功能已經穩(wěn)定發(fā)布 - <script setup>
簡而言之,<script setup>允許開發(fā)人員定義組件而無需從 JavaScript 塊中導出任何內容 - 只需定義變量并在模板中使用它們!這種編寫組件的風格在很多方面都類似于 Svelte,對于第一次接觸 Vue 的人來說,這是一個巨大的改進。
<script lang=“ts“ setup>
<script setup>是一種編譯時語法糖,用于在單文件組件 (SFC) 中使用組合 API。如果同時使用 SFC 和組合 API,則這是建議的語法。與正常語法相比,它提供了許多優(yōu)點:
- 更簡潔的代碼,更少的樣板
- 能夠使用純 TypeScript 聲明 props 和發(fā)出的事件
- 更好的運行時性能(模板編譯為同一作用域中的渲染函數,無需中間代理)
- 更好的 IDE 類型推斷性能(語言服務器從代碼中提取類型的工作量更少)
<script setup>基本
讓我們看一個例子。如果您使用的是 Options API(Vue 2 的標準),那么您的所有單文件組件將如下所示:
<template> <div>Hello, {{ name }}!</div> <input v-model="name" /> <button :disabled="!isNamePresent" @click="submitName">Submit</button> </template> <script> export default { data() { return { name: '' } }, computed: { isNamePresent() { return this.name.length > 0 } }, methods: { submitName() { console.log(this.name) } } } </script>
我們有我們的模板(一個簡單的表單)和我們的腳本塊。在腳本塊中,我們導出一個具有三個鍵的對象:名稱、計算和方法。如果你熟悉 Vue,這對你來說應該很熟悉?,F在,讓我們切換此代碼以使用 Composition API。
<template> <div>Hello, {{ name }}!</div> <input v-model="name" /> <button :disabled="!isNamePresent" @click="submitName">Submit</button> </template> <script> import { ref, computed } from 'vue' export default { setup() { const name = ref('') const isNamePresent = computed(() => name.value.length > 0) function submitName() { console.log(name.value) } return { name, isNamePresent, submitName } } } </script>
我們的組件做的事情和以前完全一樣。我們定義了狀態(tài)(名稱)、計算屬性(isNamePresent)和提交函數。如果其中任何一個不熟悉,請查看我之前關于 Vue Composition API 的文章。我們不必在要導出的對象中搭建我們的應用程序,而是可以根據需要自由定義變量。這種靈活性還允許我們根據需要從組件中提取重復的邏輯,但在這種情況下,我們的組件非常簡單。
但是,我們仍然有那個尷尬的export default說法。我們的代碼都存在于 setup 函數中,而其余的實際上只是樣板文件。我們不能直接刪除它嗎?事實上,我們現在可以!這就是
<template> <div>Hello, {{ name }}!</div> <input v-model="name" /> <button :disabled="!isNamePresent" @click="submitName">Submit</button> </template> <script setup> import { ref, computed } from 'vue' const name = ref('') const isNamePresent = computed(() => name.value.length > 0) function submitName() { console.log(name.value) } </script>
讓我們來看看這里發(fā)生了什么變化。首先,我們在腳本標簽中添加了“setup”這個詞,這為編寫 Vue 組件啟用了這種新模式。其次,我們從setup函數中獲取我們的代碼,并僅用我們的代碼替換我們現有的導出對象。一切都按預期工作!
請注意,在腳本標簽中聲明的所有內容都在組件的模板中可用。這包括非反應性變量或常量,以及實用函數或其他庫。這樣做的主要好處是您不需要手動將外部文件(例如,Constants.js)綁定為組件的值 - Vue 現在會為您處理這個問題。
基本語法
要選擇加入語法,請將該屬性添加到塊中:setup``<script>
<script setup> console.log('hello script setup') </script>
內部代碼被編譯為組件函數的內容。這意味著與正常不同,普通僅在首次導入組件時執(zhí)行一次,每次創(chuàng)建組件的實例時,內部代碼都會執(zhí)行。setup()
頂級綁定向模板公開# 使用 時,其中聲明的任何頂級綁定(包括變量、函數聲明和導入)都可以直接在模板中使用:<script setup><script setup>
<script setup> // variable const msg = 'Hello!' // functions function log() { console.log(msg) } </script> <template> <div @click="log">{{ msg }}</div> </template>
進口以同樣的方式公開。這意味著您可以在模板表達式中直接使用導入的幫助程序函數,而不必通過以下選項公開它:methods
<script setup> import { capitalize } from './helpers' </script> <template> <div>{{ capitalize('hello') }}</div> </template>
Reactivity
需要使用Reactivity API 顯式創(chuàng)建響應式狀態(tài)。與從函數返回的值類似,在模板中引用 ref 時會自動解開包裝:setup()
<script setup> import { ref } from 'vue' const count = ref(0) </script> <template> <button @click="count++">{{ count }}</button> </template>
定義組件
使用時<script setup>
,我們不必再手動定義我們導入的組件了。通過將組件導入文件,編譯器能夠自動將其添加到我們的應用程序中。讓我們通過將表單抽象為它自己的組件來更新我們的組件。我們將它命名為 Form.vue?,F在,它只是模板,我們稍后會討論邏輯。
<!-- Form.vue --> <template> <form @submit.prevent="submitHandler"> <label>Name <input type="text" /> </label> <button>Submit</button> </form> </template> <script setup> function submitHandler() { // Do something } </script> <!-- App.vue --> <template> <div>Hello, {{ name }}!</div> <Form /> </template> <script setup> import { ref } from 'vue' import Form from './components/Form.vue' const name = ref('') function submitForm() { console.log(name.value) } </script>
而已!我們的組件現在必須導入到我們的 Vue 文件中,并且它會自動在我們的模板中可用。不再有components塊占用我們文件中的空間!
現在,我們需要將name子組件作為道具傳遞給我們。但是等等,我們不能定義道具!我們沒有要添加 props 選項的對象!此外,我們需要發(fā)出表單已提交,以便我們可以觸發(fā)我們的提交。我們如何定義子組件發(fā)出的內容?
defineProps和defineEmits 我們仍然可以使用新的輔助方法defineProps和defineEmits. 來自 Vue 文檔,“defineProps并且defineEmits是編譯器宏,只能在內部使用<script setup>
。它們不需要導入,在<script setup>
處理時會被編譯掉。” 這些編譯時函數采用與標準鍵與完整導出對象一起使用的相同參數。讓我們更新我們的應用程序以使用defineProps和defineEmits。
<!-- Form.vue --> <template> <form @submit.prevent="submitHandler"> <label>Name <input v-model="name" type="text" /> </label> <button>Submit</button> </form> </template> <script setup> import { computed } from 'vue' const props = defineProps({ modelValue: { type: String, default: '' } }) const emit = defineEmits(['update:modelValue', 'submit']); const name = computed({ get () { return props.modelValue }, set(val) { emit('update:modelValue', val); } }) function submitHandler() { emit('submit') } </script> <!-- App.vue --> <template> <div>Hello, {{ name }}!</div> <Form v-model="name" @submit="submitForm" /> </template> <script setup> import { ref } from 'vue' import Form from './components/Form.vue' const name = ref('') function submitForm() { console.log(name.value) } </script>
讓我們來看看這里發(fā)生了什么變化。
首先,我們曾經defineProps期望一個 modelValue(在 Vue 3 中與 v-model 一起使用的預期道具)。 然后我們用 定義了我們的發(fā)射defineEmits,這樣我們既可以報告這個組件發(fā)射的內容,也可以訪問該emit函數(以前在 `this.$emit 上可用)。 接下來,我們創(chuàng)建一個使用自定義 getter 和設置的計算屬性。我們這樣做是為了可以輕松地在表單輸入中使用 v-model,但這不是必需的。getter 返回我們的 prop,setter 將更新事件發(fā)送到我們的父組件。 最后,我們連接了 submitHandler 函數來發(fā)出一個提交事件。 我們的 App.vue 組件或多或少與我們離開它時一樣,添加v-model="name"了@submit="submitForm"Form 子組件。這樣,我們的應用程序再次按預期工作!
其它功能 這里有更多功能可供我們使用,但它們在典型應用程序中的用例較少。
動態(tài)組件- 由于我們的組件在模板中立即可用,我們可以在編寫動態(tài)組件時使用它們(例如)。 命名空間組件- 如果您有許多從同一文件導入的組件,則可以使用import * as Form語法對這些組件進行命名空間。然后,您無需任何額外工作即可訪問<Form.Input>或。<Form.Submit> Top-Level Await - 如果您需要將 API 請求作為組件設置的一部分,您可以在組件的頂層自由使用 async/await 語法 - 無需包裝在 async 函數中!請記住,使用它的組件必須由組件在外部包裹
要記住的另一點是,您并沒有被鎖定在使用<script setup>
. 如果您將這種新語法用于組件并遇到無法完成某事的情況,或者只是想對特定情況使用 Options 語法,您可以通過添加一個額外的. 有關這方面的一個很好的例子,請參閱 Vue 文檔。
結論
這是 Vue 和 Composition API 向前邁出的一大步。事實上,Evan You 已經公開表示,這是為了成為 Vue 單文件組件未來的標準語法。來自Github 上的討論: 這有一些歷史,因為關于 Composition API 的最初提案表明打算用它完全取代 Options API,但遭到了強烈反對。盡管我們確實相信Composition API 從長遠來看有潛力成為“前進的道路”,但我們意識到(1)仍有人機工程學/工具/設計問題需要解決,(2)范式轉變不能一天之內完成。在我們可以自信地向所有 Vue 用戶推薦新的東西之前,我們需要時間和早期采用者來驗證、嘗試、采用和試驗新范式。
這實質上導致了一個“過渡期”,在此期間我們有意避免將 Composition API 聲明為“新方式”,以便我們可以執(zhí)行驗證過程并與主動采用它的用戶子集一起構建周圍的工具/生態(tài)系統(tǒng)。
現在<script setup>
,隨著 IDE 工具支持的改進,我們相信 Composition API 已達到為大多數用戶提供卓越 DX 和可擴展性的狀態(tài)。但我們需要時間來達到這一點。
在同一線程的早些時候,Evan 表達了他對 Vue 未來發(fā)展的看法:
目前推薦的方法是:
使用 SFC <script setup>
++ 組合 API 使用 VSCode + Volar(或 WebStorm,一旦它支持<script setup>
即將發(fā)布) TS 沒有嚴格要求,但如果適用,請使用 Vite 構建工具。
到此這篇關于vue3.2中setup語法糖<script lang="ts" setup>的文章就介紹到這了,更多相關vue3.2中setup語法糖內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue3.0運行npm run dev報錯Cannot find module&
本文主要介紹了vue3.0運行npm run dev報錯Cannot find module node:url,因為使用的node版本是14.15.1低于15.0.0導致,具有一定的參考價值,感興趣的可以了解一下2023-10-10vue3?組件與API直接使用的方法詳解(無需import)
這篇文章主要介紹了vue3?組件與API直接使用的方法(無需import),主要包括vue3自動導入和API的自動引入問題,本文結合示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-09-09VUE v-for循環(huán)中每個item節(jié)點動態(tài)綁定不同函數的實例
今天小編就為大家分享一篇VUE v-for循環(huán)中每個item節(jié)點動態(tài)綁定不同函數的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09