這篇文章主要介紹了Vue3中的script setup語(yǔ)法糖怎么使用的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇Vue3中的script setup語(yǔ)法糖怎么使用文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。
成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供萬(wàn)源企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、H5建站、小程序制作等業(yè)務(wù)。10年已為萬(wàn)源眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。
組合式 API:setup()
Vue 3 的 Composition API 系列里,推出了一個(gè)全新的 setup
函數(shù),它是一個(gè)組件選項(xiàng),在創(chuàng)建組件之前執(zhí)行,一旦 props 被解析,并作為組合式 API 的入口點(diǎn)。
setup
選項(xiàng)是一個(gè)接收 props
和 context
的函數(shù),我們參考文檔進(jìn)行討論。此外,我們將 setup
返回的所有內(nèi)容都暴露給組件的其余部分 (計(jì)算屬性、方法、生命周期鉤子等等) 以及組件的模板。
<script> // 這是一個(gè)基于 TypeScript 的 Vue 組件 import { defineComponent } from 'vue' export default defineComponent({ setup(props, context) { // 在這里聲明數(shù)據(jù),或者編寫函數(shù)并在這里執(zhí)行它 return { // 需要給 `<template />` 用的數(shù)據(jù)或函數(shù),在這里 `return` 出去 } }, }) </script>
新的
setup
選項(xiàng)是在組件創(chuàng)建之前, props
被解析之后執(zhí)行,是組合式 API 的入口。
注意:
在setup
中你應(yīng)該避免使用this
,因?yàn)樗粫?huì)找到組件實(shí)例。setup
的調(diào)用發(fā)生在data
property、computed
property 或methods
被解析之前,所以它們無(wú)法>在setup
中被獲取。
在添加了setup的script標(biāo)簽中,我們不必聲明和方法,這種寫法會(huì)自動(dòng)將所有頂級(jí)變量、函數(shù),均會(huì)自動(dòng)暴露給模板(template)使用
這里強(qiáng)調(diào)一句 “暴露給模板,跟暴露給外部不是一回事”
TIP:說(shuō)的通俗一點(diǎn),就是在使用 Vue 3 生命周期的情況下,整個(gè)組件相關(guān)的業(yè)務(wù)代碼,都可以放在 setup
里執(zhí)行。
因?yàn)樵?nbsp;setup
之后,其他的生命周期才會(huì)被啟用,我們對(duì)比一下Vue2的Vue3生命周期的變化
關(guān)于 Vue 生命周期的變化,可以從下表直觀地了解:
Vue 2 生命周期 | Vue 3 生命周期 | 執(zhí)行時(shí)間說(shuō)明 |
---|---|---|
beforeCreate | setup | 組件創(chuàng)建前執(zhí)行 |
created | setup | 組件創(chuàng)建后執(zhí)行 |
beforeMount | onBeforeMount | 組件掛載到節(jié)點(diǎn)上之前執(zhí)行 |
mounted | onMounted | 組件掛載完成后執(zhí)行 |
beforeUpdate | onBeforeUpdate | 組件更新之前執(zhí)行 |
updated | onUpdated | 組件更新完成之后執(zhí)行 |
beforeDestroy | onBeforeUnmount | 組件卸載之前執(zhí)行 |
destroyed | onUnmounted | 組件卸載完成后執(zhí)行 |
errorCaptured | onErrorCaptured | 當(dāng)捕獲一個(gè)來(lái)自子孫組件的異常時(shí)激活鉤子函數(shù) |
可以看到 Vue 2 生命周期里的 beforeCreate
和 created
,在 Vue 3 里已被 setup
替代。
script setup 語(yǔ)法糖
它是 Vue3 的一個(gè)新語(yǔ)法糖,在 setup
函數(shù)中。所有 ES 模塊導(dǎo)出都被認(rèn)為是暴露給上下文的值,并包含在 setup() 返回對(duì)象中。相對(duì)于之前的寫法,使用后,語(yǔ)法也變得更簡(jiǎn)單。
自動(dòng)注冊(cè)屬性和方法無(wú)需返回,直接使用
1.<script setup>
語(yǔ)法糖并不是新增的功能模塊,它只是簡(jiǎn)化了以往的組合API(compositionApi)的必須返回(return)的寫法,并且有更好的運(yùn)行時(shí)性能。
2.在 setup 函數(shù)中:所有 ES 模塊導(dǎo)出都被認(rèn)為是暴露給上下文的值,并包含在 setup() 返回對(duì)象中。相對(duì)于之前的寫法,使用后,語(yǔ)法也變得更簡(jiǎn)單。
你不必?fù)?dān)心setup語(yǔ)法糖的學(xué)習(xí)成本,他是組合式API的簡(jiǎn)化,并沒(méi)有新增的知識(shí)點(diǎn)。你只需要了解一些用法和細(xì)微的不同之處,甚至比之前寫setup()還要順手!
使用方式也很簡(jiǎn)單,只需要在 script 標(biāo)簽加上 setup 關(guān)鍵字即可
<script setup> </script>
組件核心 API 的使用
在 script setup 中,引入的組件可以直接使用,無(wú)需再通過(guò)components進(jìn)行注冊(cè),并且無(wú)法指定當(dāng)前組件的名字,它會(huì)自動(dòng)以文件名為主,也就是不用再寫name屬性了。
示例:
<template> <Child /> </template> <script setup> import Child from '@/components/Child.vue' </script>
代碼示列
:通過(guò)defineProps
指定當(dāng)前 props 類型,獲得上下文的props對(duì)象。
示例:
<script setup> import { defineProps } from 'vue' const props = defineProps({ title: String, }) </script> <!-- 或者 --> <script setup> import { ref,defineProps } from 'vue'; type Props={ msg:string } defineProps<Props>(); </script>
使用defineEmit
定義當(dāng)前組件含有的事件,并通過(guò)返回的上下文去執(zhí)行 emit。
代碼示列:
<script setup> import { defineEmits } from 'vue' const emit = defineEmits(['change', 'delete']) </script>
defineProps 用來(lái)接收父組件傳來(lái)的 props ; defineEmits 用來(lái)聲明觸發(fā)的事件。
//父組件 <template> <Child @getChild="getChild" :title="msg" /> </template> <script setup> import { ref } from 'vue' import Child from '@/components/Child.vue' const msg = ref('parent value') const getChild = (e) => { // 接收父組件傳遞過(guò)來(lái)的數(shù)據(jù) console.log(e); // child value } </script>
子組件通過(guò) defineProps 接收父組件傳過(guò)來(lái)的數(shù)據(jù),子組件通過(guò) defineEmits 定義事件發(fā)送信息給父組件//子組件
<template>
<div @click="toEmits">Child Components</div>
</template>
<script setup>
// defineEmits,defineProps無(wú)需導(dǎo)入,直接使用
const emits = defineEmits(['getChild']);
const props = defineProps({
title: {
type: String,
defaule: 'defaule title'
}
});
const toEmits = () => {
emits('getChild', 'child value') // 向父組件傳遞數(shù)據(jù)
}
// 獲取父組件傳遞過(guò)來(lái)的數(shù)據(jù)
console.log(props.title); // parent value
</script>
useSlots()
和 useAttrs()
注:useContext API 被棄用,取而代之的是更加細(xì)分的 api。
可以通過(guò)useContext
從上下文中獲取 slots 和 attrs。不過(guò)提案在正式通過(guò)后,廢除了這個(gè)語(yǔ)法,被拆分成了useAttrs
和useSlots
。
useAttrs
:見名知意,這是用來(lái)獲取 attrs 數(shù)據(jù),但是這和 vue2 不同,里面包含了 class
、屬性
、方法
。
<template> <component v-bind='attrs'></component> </template> <srcipt setup> const attrs = useAttrs(); <script>
useSlots
: 顧名思義,獲取插槽數(shù)據(jù)。
使用示例:
// 舊 <script setup> import { useContext } from 'vue' const { slots, attrs } = useContext() </script> // 新 <script setup> import { useAttrs, useSlots } from 'vue' const attrs = useAttrs() const slots = useSlots() </script>
傳統(tǒng)的寫法,我們可以在父組件中,通過(guò) ref 實(shí)例的方式去訪問(wèn)子組件的內(nèi)容,但在 script setup 中,該方法就不能用了,setup 相當(dāng)于是一個(gè)閉包,除了內(nèi)部的 template
模板,誰(shuí)都不能訪問(wèn)內(nèi)部的數(shù)據(jù)和方法。
<script setup>
的組件默認(rèn)不會(huì)對(duì)外部暴露任何內(nèi)部聲明的屬性。
如果有部分屬性要暴露出去,可以使用defineExpose
注意:目前發(fā)現(xiàn)
defineExpose
暴露出去的屬性以及方法都是unknown
類型,如果有修正類型的方法,歡迎評(píng)論區(qū)補(bǔ)充。
如果需要對(duì)外暴露 setup 中的數(shù)據(jù)和方法,需要使用 defineExpose API。示例:
//子組件 <template> {{msg}} </template> <script setup> import { ref } from 'vue' let msg = ref("Child Components"); let num = ref(123); // defineExpose無(wú)需導(dǎo)入,直接使用 defineExpose({ msg, num }); </script>
//父組件
<template>
<Child ref="child" />
</template>
<script setup>
import { ref, onMounted } from 'vue'
import Child from '@/components/Child.vue'
let child = ref(null);
onMounted(() => {
console.log(child.value.msg); // Child Components
console.log(child.value.num); // 123
})
</script>
定義響應(yīng)變量、函數(shù)、監(jiān)聽、計(jì)算屬性computed
<script setup > import { ref,computed,watchEffect } from 'vue'; const count = ref(0); //不用 return ,直接在 templete 中使用 const addCount=()=>{ //定義函數(shù),使用同上 count.value++; } //創(chuàng)建一個(gè)只讀的計(jì)算屬性 ref: const plusOne = computed(() => count.value + 1) // 創(chuàng)建一個(gè)可寫的計(jì)算屬性 ref const plusOne = computed({ get: () => count.value + 1, set: (val) => { count.value = val - 1 } }) //定義監(jiān)聽,使用同上 //...some code else watchEffect(()=>console.log(count.value)); </script>
1、watch是惰性執(zhí)行,也就是只有監(jiān)聽的值發(fā)生變化的時(shí)候才會(huì)執(zhí)行,但是watchEffect不同,每次代碼加載watchEffect都會(huì)執(zhí)行(忽略watch第三個(gè)參數(shù)的配置,如果修改配置項(xiàng)也可以實(shí)現(xiàn)立即執(zhí)行)
2、watch需要傳遞監(jiān)聽的對(duì)象,watchEffect不需要
3、watch只能監(jiān)聽響應(yīng)式數(shù)據(jù):ref定義的屬性和reactive定義的對(duì)象,如果直接監(jiān)聽reactive定義對(duì)象中的屬性是不允許的,除非使用函數(shù)轉(zhuǎn)換一下
4、watchEffect如果監(jiān)聽reactive定義的對(duì)象是不起作用的,只能監(jiān)聽對(duì)象中的屬性。
返回一個(gè)對(duì)象的響應(yīng)式代理。
<script setup> import { reactive, onUnmounted } from 'vue' const state = reactive({ counter: 0 }) // 定時(shí)器 每秒都會(huì)更新數(shù)據(jù) const timer = setInterval(() => { state.counter++ }, 1000); onUnmounted(() => { clearInterval(timer); }) </script> <template> <div>{{state.counter}}</div> </template>
使用ref也能達(dá)到我們預(yù)期的'counter',并且在模板中,vue進(jìn)行了處理,我們可以直接使用counter而不用寫counter.value.
ref和reactive的關(guān)系:
ref是一個(gè){value:'xxxx'}的結(jié)構(gòu),value是一個(gè)reactive對(duì)象
曾經(jīng)的提案中,如果需要暴露變量到模板,需要在變量前加入export聲明:
export const count = ref(0)
不過(guò)在新版的提案中,無(wú)需export聲明,編譯器會(huì)自動(dòng)尋找模板中使用的變量,只需像下面這樣簡(jiǎn)單的聲明,即可在模板中使用該變量
<script setup >
import { ref } from 'vue'
const counter = ref(0);//不用 return ,直接在 templete 中使用
const timer = setInterval(() => {
counter.value++
}, 1000)
onUnmounted(() => {
clearInterval(timer);
})
</script>
<template>
<div>{{counter}}</div>
</template>
useCSSModule
:CSS Modules 是一種 CSS 的模塊化和組合系統(tǒng)。vue-loader 集成 CSS Modules,可以作為模擬 scoped CSS。允許在單個(gè)文件組件的setup
中訪問(wèn)CSS模塊。此 api 本人用的比較少,不過(guò)多做介紹。
useCssVars
: 此 api 暫時(shí)資料比較少。介紹v-bind in styles
時(shí)提到過(guò)。
useTransitionState
: 此 api 暫時(shí)資料比較少。
useSSRContext
: 此 api 暫時(shí)資料比較少。
注意在vue3的源代碼中,setup執(zhí)行完畢,函數(shù) getCurrentInstance 內(nèi)部的有個(gè)值會(huì)釋放對(duì) currentInstance 的引用,await 語(yǔ)句會(huì)導(dǎo)致后續(xù)代碼進(jìn)入異步執(zhí)行的情況。所以上述例子中最后一個(gè) getCurrentInstance() 會(huì)返回 null,建議使用變量保存第一個(gè) getCurrentInstance() 返回的引用.
<script setup> const post = await fetch(`/api/post/1`).then((r) => r.json()) </script>
<script setup>
中可以使用頂層 await
。結(jié)果代碼會(huì)被編譯成 async setup()
:
<script setup> const post = await fetch(`/api/post/1`).then(r => r.json()) </script>
另外,await 的表達(dá)式會(huì)自動(dòng)編譯成在
await
之后保留當(dāng)前組件實(shí)例上下文的格式。
注意
async setup()
必須與Suspense
組合使用,Suspense
目前還是處于實(shí)驗(yàn)階段的特性。我們打算在將來(lái)的某個(gè)發(fā)布版本中開發(fā)完成并提供文檔 - 如果你現(xiàn)在感興趣,可以參照 tests 看它是如何工作的。
配置項(xiàng)的缺失,有時(shí)候我們需要更改組件選項(xiàng),在setup
中我們目前是無(wú)法做到的。我們需要在上方
再引入一個(gè) script
,在上方寫入對(duì)應(yīng)的 export
即可,需要單開一個(gè) script。
<script setup>
可以和普通的 <script>
一起使用。普通的 <script>
在有這些需要的情況下或許會(huì)被使用到:
無(wú)法在 <script setup>
聲明的選項(xiàng),例如 inheritAttrs
或通過(guò)插件啟用的自定義的選項(xiàng)。
聲明命名導(dǎo)出。
運(yùn)行副作用或者創(chuàng)建只需要執(zhí)行一次的對(duì)象。
在script setup 外使用export default,其內(nèi)容會(huì)被處理后放入原組件聲明字段。
<script> // 普通 `<script>`, 在模塊范圍下執(zhí)行(只執(zhí)行一次) runSideEffectOnce() // 聲明額外的選項(xiàng) export default { name: "MyComponent", inheritAttrs: false, customOptions: {} } </script> <script setup> import HelloWorld from '../components/HelloWorld.vue' // 在 setup() 作用域中執(zhí)行 (對(duì)每個(gè)實(shí)例皆如此) // your code </script> <template> <div> <HelloWorld msg="Vue3 + TypeScript + Vite"/> </div> </template>
注意:Vue 3 SFC 一般會(huì)自動(dòng)從組件的文件名推斷出組件的 name。在大多數(shù)情況下,不需要明確的 name 聲明。唯一需要的情況是當(dāng)你需要
<keep-alive>
包含或排除或直接檢查組件的選項(xiàng)時(shí),你需要這個(gè)名字。
關(guān)于“Vue3中的script setup語(yǔ)法糖怎么使用”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“Vue3中的script setup語(yǔ)法糖怎么使用”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網(wǎng)站標(biāo)題:Vue3中的scriptsetup語(yǔ)法糖怎么使用
網(wǎng)頁(yè)地址:http://www.rwnh.cn/article8/gpodip.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、網(wǎng)站設(shè)計(jì)公司、建站公司、云服務(wù)器、品牌網(wǎng)站制作、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)