大家好,我是若川。今天分享一篇?Vue 3.2 版本的文章。
查看源碼等系列文章。學習源碼整體架構系列、年度總結、JS基礎系列
1前言
8.10號凌晨,尤雨溪在微博平臺官宣 Vue 3.2 版本正式發布:
此版本包含一系列重要的新功能與性能改進,但并不涉及任何重大變更。本文主要介紹一些相對重要 Vue3.2新特性,如需了解更多請查閱官方文檔!
2新的 SFC 功能
關于單文件組件(SFC,即.vue 文件)的兩項功能已經由實驗狀態正式畢業,現提供穩定版本:
<script setup>
?是一種編譯時語法糖,能夠極大改善在 SFC 中使用 Composition API 時的開發者體驗。<style> v-bind
?用于在 SFC?<style>
?標簽中啟用組件狀態驅動的動態 CSS 值。
1、<script setup>
在<script setup>
中,我們不必聲明export default
和setup
方法,這種寫法會自動將所有頂級變量、函數,均會自動暴露給模板(template)使用。我們先來通過一個例子,對比script setup
前后寫法的不同,直觀感受下setup
帶給我們的便利:
//?script?setup之前的寫法
<template><div><div>浪里行舟</div><Card>{{?message?}}</Card></div>
</template>
<script?lang="ts">
import?{?ref,?defineComponent?}?from?"vue";
import?Card?from?"./components/Card.vue";export?default?defineComponent({components:?{Card,},setup()?{const?message?=?ref("vue?3.2?新特性?script?setup");return?{?message?};},
});
</script>
//?script?setup的寫法
<template><div><div>浪里行舟</div><Card>{{message}}</Card></div>
</template><script?lang="ts"?setup>
import?{?ref?}?from?"vue";
import?Card?from?"./components/Card.vue";
const?message?=?ref("vue?3.2?新特性?script?setup");
</script>
從上面的例子來看,<script setup>
語法省去了組件Card的注冊步驟,以及return變量message的語句,使得代碼更為精簡。關于<script setup>
的使用還有些細節和注意事項,我將會在下一篇文章詳細介紹。
2、<style> v-bind
挺有趣的一個新特性,通過這個指令,Vue SFC 的 CSS 靈活性將大大提高。該指令適用于<script setup>
, 并支持 JavaScript 表達式(必須用引號括起來)。
<script?setup>
import?{?ref?}?from?"vue";
const?color?=?ref("pink");
color.value?=?"green";
const?fontSize?=?ref("18px");
</script>
<template><h2>浪里行舟</h2><h1>Hello?Vue3.2</h1><h2>{{?color?}}</h2><button?@click="color?=?'red'">color?red</button><button?@click="color?=?'yellow'">color?yellow</button><button?@click="color?=?'blue'">color?blue</button><button?@click="fontSize?=?'40px'">fontSize?40px</button>
</template>
<style?scoped>
h1?{color:?v-bind(color);
}
h2?{font-size:?v-bind(fontSize);
}
</style>

點擊按鈕更改color
?或者?fontSize
的數值,可以看到頁面樣式也會響應式變化。其原理就是自定義屬性將通過內聯樣式應用于組件的根元素,并在數值更改時進行響應更新。
3v-memo
3.2 版本為 Vue 的響應式系統帶來了一系列重大性能改進,具體包括:
更高效的 ref 實現(讀取速度提高約 260%,寫入速度提高約 50%)
依賴項跟蹤速度提高約 40%
內存使用量減少約 17%
新版本還提供新的?v-memo
?指令,可實現對部分模板樹的記憶功能。當v-memo
?命中時,不僅允許 Vue 跳過虛擬 DOM 差異、甚至可以完全跳過新 VNode 的創建步驟。雖然這個指令使用頻率不高,但它提供了一個逃生艙來在某些情況下(例如處理大型?v-for
?列表)獲取最大性能。
<div?v-for="user?of?users"?:key="user.id"?v-memo="[user.name]">{{?user.name?}}
</div>
這個例子使用v-memo
,不會重新創建虛擬元素,并且會重新使用前一個元素,除非v-memo
(此處為用戶名)的條件發生變化。這可能看起來是一個很小的改進,但如果您渲染大量元素,它實際上是性能的巨大改進。
其實v-memo
可以接受一組條件,請看下面的例子:
<div?v-for="user?of?users"?:key="user.id"?v-memo="[user.name,?selectedUserId?===?user.id]"><p?:class="{?red:?selectedUserId?===?user.id?}">{{?user.name?}}</p>
</div>
此時如果user.name
或selectedUserId
發生變化,div
則將更新。
4新 ref 語法糖(實驗性)
$ref()
避免在更新 ref 值時需要使用.value
,可以讓代碼更加精簡!請看下面例子:
<template><input?type="number"?v-model="count">?*?5€<h1>{{?total?}}</h1>
</template><script?setup>let?count?=?$ref(0)let?total?=?$computed(()?=>?count?*?5)
</script>
??注意:這還是一個實驗性特性,所以請謹慎使用,因為它將來可能會發生變化。該提案還引入了其他新的語法糖,包括$computed()
、$fromRefs()
和$raw()
。
5Expose API
Vue 3.2 添加了一個新的?Expose API
?來定義組件公開的內容。Expose API
?的設想是提供一個像?expose({ ...publicMembers })
?這樣的組合式 API,這樣組件的作者就可以在?setup()
?中使用該 API 來精細設定公開暴露給其他組件的內容。
下例中,該組件只能公開其toggle
函數,而不能公開其collapsed
變量。
export?default?defineComponent({setup(props,?{?expose?})?{const?collapsed?=?ref(true)const?toggle?=?()?=>?{collapsed.value?=?!collapsed.value;}//?only?expose?`toggle`?to?the?parent?componentexpose({?toggle?})return?{?collapsed,?toggle?}}
})
請注意,所有$
實例屬性都會自動公開,因此使用Collapse
的組件可以訪問$props
,$slots
以及其他。<script setup>
通過調用defineExpose()
函數使用時也可以這樣做。
當你在封裝組件時,如果嫌ref
?中暴露的內容過多,不妨用?Expose API
??來約束一下輸出吧!
6Effect Scope API
Vue 3.2版本引入了新的?Effect scope API
,用于創建一個effect Scope
對象,該對象可以捕獲在其中創建的反應性效果(例如computed
?或?watchers
),以便可以將這些效果放在一起并輕松處理它們。它可以更輕松地在組件上下文之外使用 Vue 的響應式 API,同時也在組件之內解鎖了多種高級用例。Effect scope
?是一種高級 API,主要供庫作者使用。
我們知道watch
,?watchEffect
,computed
等都是綁定到一個特定的組件實例上的,在組件銷毀的時候會被 Vue 自動銷毀。這可確保應用程序沒有內存泄漏。但是如果你想在組件之外使用這些函數,例如在你正在編寫的庫中,你需要手動處理它們,請看下例:
import?{?ref,?computed,?stop,?watchEffect?}?from?'vue';const?quantity?=?ref(0);
const?price?=?ref(10);
const?total?=?computed(()?=>?quantity.value?*?price.value);
const?stopWatch?=?watchEffect(()?=>?console.log(`total?changed?to?${total.value}`));let?effectsToStop?=?[];
effectsToStop.push(()?=>?stop(total));
effectsToStop.push(stopWatch);
const?stopAll?=?()?=>?{effectsToStop.forEach(f?=>?f())effectsToStop?=?[]
};
//?calling?`stopAll()`?disposes?of?all?effects
7.prop 和 .attr 修飾符
.prop
?:?被用于強制綁定 DOM 屬性 (property).attr
?:?被用于強制綁定 DOM 屬性 (attribute)
v-bind 默認綁定到 DOM 節點的 attribute 上,使用.prop
修飾符后,設置的自定義屬性不會在渲染后的 HTML 標簽里顯示,而.attr
修飾符則剛好相反!
.prop
修飾符用途:
通過自定義屬性存儲變量,避免暴露數據
防止污染 HTML 結構
<input?id="input"?type="foo"?value="11"?:data.prop="inputData"></input>
//?渲染后HTML標簽結構
<input?id="input"?type="foo"?value="11"></input>
看了它的用途就知道,如果你不想你的屬性顯示在html標簽里面,就用.prop
修飾符吧!
另外這兩個修飾符有簡寫的語法:
<a?:title.prop="firstTabTooltip"?:aria-selected.attr="isFirstTabSelected">First?tab</a><!--?簡寫?-->
<a?.title="firstTabTooltip"?^aria-selected="isFirstTabSelected">First?tab</a>
8Web 組件
Vue 3.2 引入了新的?defineCustomElement
?方法,可以使用 Vue 組件 API 輕松創建原生自定義元素:
import?{?defineCustomElement?}?from?'vue'const?MyVueElement?=?defineCustomElement({//?常規?Vue?組件選項
})//?注冊自定義元素。
//?注冊完成后,此頁面上的所有?`<my-vue-element>`?標簽
//?都將將升級。
customElements.define('my-vue-element',?MyVueElement)
此 API 允許開發者們創建由 Vue 驅動的 UI 組件庫。這些庫可以支持任何框架選項,甚至能夠在無框架情況下正常使用。
9總結
以上諸多特性,最讓我感興趣的是setup script
,此語法使單個文件組件更簡單!只需要給?script
?標簽添加一個?setup
?屬性,那么整個?script
?就直接會變成setup
函數,所有頂級變量、函數,均會自動暴露給模板使用(無需再一個個 return了),開發效率將大大的提高!
以至于連尤大也在微博上呼吁大家:“如果你能用Vue3卻還在用 Options API,現在有了< script setup>沒有理由不換 Composition API了”
10參考資料
Vue 3.2 Released!
Vue 3.2 Released!
What's new in Vue 3.2?
v-bind 指令常用修飾符
Vue3 官方文檔
Vue 3.2正式發布,script setup + TS + Volar = 真香
最近組建了一個湖南人的前端交流群,如果你是湖南人可以加我微信?ruochuan12?私信 湖南?拉你進群。
推薦閱讀
我在阿里招前端,該怎么幫你(可進面試群)
我讀源碼的經歷
面對 this 指向丟失,尤雨溪在 Vuex 源碼中是怎么處理的
老姚淺談:怎么學JavaScript?
·················?若川簡介?·················
你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》多篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,活躍在知乎@若川,掘金@若川。致力于分享前端開發經驗,愿景:幫助5年內前端人走向前列。
識別上方二維碼加我微信、拉你進源碼共讀群
今日話題
略。歡迎分享、收藏、點贊、在看我的公眾號文章~