一文帶你掌握?Vue3.5常用特性
響應(yīng)式 Props 解構(gòu)
Vue3.5 中 Props 正式支持解構(gòu)了,并添加了響應(yīng)式跟蹤
設(shè)置默認(rèn)值
使用 JavaScript 原生的默認(rèn)值語法聲明 props 默認(rèn)值
以前
const props = withDefaults( defineProps<{ count?: number msg?: string }>(), { count: 0, msg: 'hello' } )
現(xiàn)在
const { count = 0, msg = 'hello' } = defineProps<{ count?: number message?: string }>()
響應(yīng)式解構(gòu)
當(dāng)在同一個 <script setup> 代碼塊中訪問由 defineProps 解構(gòu)的變量時,Vue 編譯器會自動在前面添加 props
以前
const { foo } = defineProps(['foo']) watchEffect(() => { // 在 3.5 之前只運行一次 console.log(foo) })
現(xiàn)在
const { foo } = defineProps(['foo']) watchEffect(() => { // 在 3.5 中在 "foo" prop 變化時重新執(zhí)行 console.log(foo) // `foo` 由編譯器轉(zhuǎn)換為 `props.foo`,以上等同于 `console.log(props.foo)` })
與之類似,監(jiān)聽解構(gòu)的 prop 變量 或 將其傳遞到可組合項中同時保留響應(yīng)性 時需要將其包裝在 getter 中
以前
const { foo } = defineProps(['foo']) watch(foo, /* ... */)
現(xiàn)在:
// watch(foo, /* ... */) 等價于 watch(props.foo, ...),我們給 watch 傳遞的是一個值而不是響應(yīng)式數(shù)據(jù)源 watch(() => foo, /* ... */) // 傳遞解構(gòu)的 prop 到外部函數(shù)中并保持響應(yīng)性 useComposable(() => foo)
監(jiān)聽(watch / watcheffect) 相關(guān)
watch 支持指定深度 deep: number
watch 的 deep 選項現(xiàn)在支持傳入數(shù)字,來指定監(jiān)聽的深度
const state = ref({ a: { b: { c: 1 } } }) watch(state, (newValue) => { console.log(`state: ${newValue}`) }, { deep: 2 } ) state.a.b = { c: 2 } // 更改了第二層的屬性,觸發(fā)監(jiān)聽 state.a.b.c = 2 // 更改了第三層的屬性,不觸發(fā)監(jiān)聽
清理函數(shù) onWatcherCleanup / onEffectCleanup
以前我們在監(jiān)聽函數(shù)中要發(fā)送異步請求時,很可能發(fā)生請求參數(shù)發(fā)生變化的情況,這時我們需要設(shè)置全局變量存儲 AbortController,并在組件卸載之前清理它
import { watch, onBeforeUnmount } from "vue" let controller = new AbortController() watch(state, (newValue) => { controller.abort() // 取消上一次的請求 controller = new AbortController() fetch(`/api/${newValue}`, { signal: controller.signal }).then(() => { // 回調(diào)邏輯 }) }); // 組件卸載前也要清理 onBeforeUnmount(() => controller.abort())
現(xiàn)在有了清理函數(shù) onWatcherCleanup / onEffectCleanup 后,我們可以直接調(diào)用它來清理之前的 調(diào)用(異步)函數(shù)/請求
import { watch, onWatcherCleanup } from 'vue' watch(id, (newId) => { const controller = new AbortController() fetch(`/api/${newId}`, { signal: controller.signal }).then(() => { // 回調(diào)邏輯 }) onWatcherCleanup(() => { // 終止過期請求 controller.abort() }) })
onEffectCleanup 函數(shù)寫法類似以上,不同的是導(dǎo)入來源
import { onEffectCleanup } from "@vue/reactivity";
[!WARNING]
onWatcherCleanup 僅在 Vue 3.5+ 中支持,并且必須在 watchEffect 效果函數(shù)或 watch 回調(diào)函數(shù)的同步執(zhí)行期間調(diào)用:你不能在異步函數(shù)的 await 語句之后調(diào)用它。
watch 返回值增強
watch 返回值中新增 暫停/恢復(fù)偵聽器,可以更細(xì)致的控制監(jiān)聽作用范圍
const { stop, pause, resume } = watch(() => {}) // 暫停偵聽器 pause() // 稍后恢復(fù) resume()
SSR 改進
惰性激活 Lazy Hydration
異步組件可以通過 defineAsyncComponent() API 中的 hydrate 選項來控制何時進行激活
在空閑時進行激活
import { defineAsyncComponent, hydrateOnIdle } from 'vue' const AsyncComp = defineAsyncComponent({ loader: () => import('./Comp.vue'), hydrate: hydrateOnIdle(/* 傳遞可選的最大超時 */) })
在元素變?yōu)榭梢姇r激活
import { defineAsyncComponent, hydrateOnVisible } from 'vue' const AsyncComp = defineAsyncComponent({ loader: () => import('./Comp.vue'), hydrate: hydrateOnVisible() })
自定義策略
import { defineAsyncComponent, type HydrationStrategy } from 'vue' const myStrategy: HydrationStrategy = (hydrate, forEachElement) => { // forEachElement 是一個遍歷組件未激活的 DOM 中所有根元素的輔助函數(shù), // 因為根元素可能是一個片段而非單個元素 forEachElement(el => { // ... }) // 準(zhǔn)備好時調(diào)用 `hydrate` hydrate() return () => { // 如必要,返回一個銷毀函數(shù) } } const AsyncComp = defineAsyncComponent({ loader: () => import('./Comp.vue'), hydrate: myStrategy })
其他
請查看 Vue3官方文檔 - 惰性激活,這里不再贅述
useId() 生成唯一應(yīng)用ID
用于為無障礙屬性或表單元素生成每個應(yīng)用內(nèi)唯一的 ID。在我們?nèi)粘?yīng)用中,主要可以解決服務(wù)端和客戶端生成的id不一樣導(dǎo)致渲染報錯的問題
<script setup> import { useId } from 'vue' const id = useId() </script> <template> <form> <label :for="id">Name:</label> <input :id="id" type="text" /> </form> </template>
data-allow-mismatch
如果客戶端值不可避免地與其服務(wù)端對應(yīng)值(例如日期)不同,我們可以使用屬性 data-allow-mismatch 來避免由此產(chǎn)生的激活不匹配警告
<span data-allow-mismatch>{{ data.toLocaleString() }}</span>
還可以指定特定類型。允許的值有:text,children (僅允許直接子組件不匹配),class,style,attribute
其他
useTemplateRef()
返回一個淺層 ref,可以更直觀的綁定元素,同時也支持動態(tài)綁定
<script setup> import { ref, useTemplateRef, onMounted } from 'vue' const targetRef = ref('input1') const inputRef = useTemplateRef<HTMLInputElement>(targetRef.value) onMounted(() => { inputRef.value.focus() }) </script> <template> <input ref="input1" /> <input ref="input2" /> </template>
其他不常用的就不在說明了
到此這篇關(guān)于一文帶你掌握 Vue3.5常用特性的文章就介紹到這了,更多相關(guān)Vue3.5常用特性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Antd-vue Table組件添加Click事件,實現(xiàn)點擊某行數(shù)據(jù)教程
這篇文章主要介紹了Antd-vue Table組件添加Click事件,實現(xiàn)點擊某行數(shù)據(jù)教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11結(jié)合mint-ui移動端下拉加載實踐方法總結(jié)
下面小編就為大家?guī)硪黄Y(jié)合mint-ui移動端下拉加載實踐方法總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11Vue中video標(biāo)簽如何實現(xiàn)不靜音自動播放
最近在做大屏展示需要在一開始播放引導(dǎo)視頻,產(chǎn)生自動播放需求,下面這篇文章主要給大家介紹了關(guān)于Vue中video標(biāo)簽如何實現(xiàn)不靜音自動播放的相關(guān)資料,需要的朋友可以參考下2023-01-01