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

