【Vuejs】1072- Vue 3.2 有哪些新變化?
1前言
8.10號(hào)凌晨,尤雨溪在微博平臺(tái)官宣 Vue 3.2 版本正式發(fā)布:
此版本包含一系列重要的新功能與性能改進(jìn),但并不涉及任何重大變更。本文主要介紹一些相對(duì)重要 Vue3.2新特性,如需了解更多請(qǐng)查閱官方文檔!
2新的 SFC 功能
關(guān)于單文件組件(SFC,即.vue 文件)的兩項(xiàng)功能已經(jīng)由實(shí)驗(yàn)狀態(tài)正式畢業(yè),現(xiàn)提供穩(wěn)定版本:
<script setup>是一種編譯時(shí)語法糖,能夠極大改善在 SFC 中使用 Composition API 時(shí)的開發(fā)者體驗(yàn)。<style> v-bind用于在 SFC<style>標(biāo)簽中啟用組件狀態(tài)驅(qū)動(dòng)的動(dòng)態(tài) CSS 值。
1、<script setup>
在<script setup>中,我們不必聲明export default和setup方法,這種寫法會(huì)自動(dòng)將所有頂級(jí)變量、函數(shù),均會(huì)自動(dòng)暴露給模板(template)使用。我們先來通過一個(gè)例子,對(duì)比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的注冊(cè)步驟,以及return變量message的語句,使得代碼更為精簡(jiǎn)。關(guān)于<script setup>的使用還有些細(xì)節(jié)和注意事項(xiàng),我將會(huì)在下一篇文章詳細(xì)介紹。
2、<style> v-bind
挺有趣的一個(gè)新特性,通過這個(gè)指令,Vue SFC 的 CSS 靈活性將大大提高。該指令適用于<script setup>, 并支持 JavaScript 表達(dá)式(必須用引號(hào)括起來)。
<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>

點(diǎn)擊按鈕更改color 或者 fontSize的數(shù)值,可以看到頁面樣式也會(huì)響應(yīng)式變化。其原理就是自定義屬性將通過內(nèi)聯(lián)樣式應(yīng)用于組件的根元素,并在數(shù)值更改時(shí)進(jìn)行響應(yīng)更新。
3v-memo
3.2 版本為 Vue 的響應(yīng)式系統(tǒng)帶來了一系列重大性能改進(jìn),具體包括:
更高效的 ref 實(shí)現(xiàn)(讀取速度提高約 260%,寫入速度提高約 50%) 依賴項(xiàng)跟蹤速度提高約 40% 內(nèi)存使用量減少約 17%
新版本還提供新的 v-memo 指令,可實(shí)現(xiàn)對(duì)部分模板樹的記憶功能。當(dāng)v-memo 命中時(shí),不僅允許 Vue 跳過虛擬 DOM 差異、甚至可以完全跳過新 VNode 的創(chuàng)建步驟。雖然這個(gè)指令使用頻率不高,但它提供了一個(gè)逃生艙來在某些情況下(例如處理大型 v-for 列表)獲取最大性能。
<div v-for="user of users" :key="user.id" v-memo="[user.name]">
{{ user.name }}
</div>
這個(gè)例子使用v-memo,不會(huì)重新創(chuàng)建虛擬元素,并且會(huì)重新使用前一個(gè)元素,除非v-memo(此處為用戶名)的條件發(fā)生變化。這可能看起來是一個(gè)很小的改進(jìn),但如果您渲染大量元素,它實(shí)際上是性能的巨大改進(jìn)。
其實(shí)v-memo可以接受一組條件,請(qǐng)看下面的例子:
<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>
此時(shí)如果user.name或selectedUserId發(fā)生變化,div則將更新。
4新 ref 語法糖(實(shí)驗(yàn)性)
$ref()避免在更新 ref 值時(shí)需要使用.value,可以讓代碼更加精簡(jiǎn)!請(qǐng)看下面例子:
<template>
<input type="number" v-model="count"> * 5€
<h1>{{ total }}</h1>
</template>
<script setup>
let count = $ref(0)
let total = $computed(() => count * 5)
</script>
??注意:這還是一個(gè)實(shí)驗(yàn)性特性,所以請(qǐng)謹(jǐn)慎使用,因?yàn)樗鼘砜赡軙?huì)發(fā)生變化。該提案還引入了其他新的語法糖,包括$computed()、$fromRefs()和$raw()。
5Expose API
Vue 3.2 添加了一個(gè)新的 Expose API 來定義組件公開的內(nèi)容。Expose API 的設(shè)想是提供一個(gè)像 expose({ ...publicMembers }) 這樣的組合式 API,這樣組件的作者就可以在 setup() 中使用該 API 來精細(xì)設(shè)定公開暴露給其他組件的內(nèi)容。
下例中,該組件只能公開其toggle函數(shù),而不能公開其collapsed變量。
export default defineComponent({
setup(props, { expose }) {
const collapsed = ref(true)
const toggle = () => {
collapsed.value = !collapsed.value;
}
// only expose `toggle` to the parent component
expose({ toggle })
return { collapsed, toggle }
}
})
請(qǐng)注意,所有$實(shí)例屬性都會(huì)自動(dòng)公開,因此使用Collapse的組件可以訪問$props,$slots以及其他。<script setup>通過調(diào)用defineExpose()函數(shù)使用時(shí)也可以這樣做。
當(dāng)你在封裝組件時(shí),如果嫌ref 中暴露的內(nèi)容過多,不妨用 Expose API 來約束一下輸出吧!
6Effect Scope API
Vue 3.2版本引入了新的 Effect scope API,用于創(chuàng)建一個(gè)effect Scope對(duì)象,該對(duì)象可以捕獲在其中創(chuàng)建的反應(yīng)性效果(例如computed 或 watchers),以便可以將這些效果放在一起并輕松處理它們。它可以更輕松地在組件上下文之外使用 Vue 的響應(yīng)式 API,同時(shí)也在組件之內(nèi)解鎖了多種高級(jí)用例。Effect scope 是一種高級(jí) API,主要供庫作者使用。
我們知道watch, watchEffect,computed等都是綁定到一個(gè)特定的組件實(shí)例上的,在組件銷毀的時(shí)候會(huì)被 Vue 自動(dòng)銷毀。這可確保應(yīng)用程序沒有內(nèi)存泄漏。但是如果你想在組件之外使用這些函數(shù),例如在你正在編寫的庫中,你需要手動(dòng)處理它們,請(qǐng)看下例:
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: 被用于強(qiáng)制綁定 DOM 屬性 (property).attr: 被用于強(qiáng)制綁定 DOM 屬性 (attribute)
v-bind 默認(rèn)綁定到 DOM 節(jié)點(diǎn)的 attribute 上,使用.prop修飾符后,設(shè)置的自定義屬性不會(huì)在渲染后的 HTML 標(biāo)簽里顯示,而.attr修飾符則剛好相反!
.prop修飾符用途:
通過自定義屬性存儲(chǔ)變量,避免暴露數(shù)據(jù) 防止污染 HTML 結(jié)構(gòu)
<input id="input" type="foo" value="11" :data.prop="inputData"></input>
// 渲染后HTML標(biāo)簽結(jié)構(gòu)
<input id="input" type="foo" value="11"></input>
看了它的用途就知道,如果你不想你的屬性顯示在html標(biāo)簽里面,就用.prop修飾符吧!
另外這兩個(gè)修飾符有簡(jiǎn)寫的語法:
<a :title.prop="firstTabTooltip" :aria-selected.attr="isFirstTabSelected">First tab</a>
<!-- 簡(jiǎn)寫 -->
<a .title="firstTabTooltip" ^aria-selected="isFirstTabSelected">First tab</a>
8Web 組件
Vue 3.2 引入了新的 defineCustomElement 方法,可以使用 Vue 組件 API 輕松創(chuàng)建原生自定義元素:
import { defineCustomElement } from 'vue'
const MyVueElement = defineCustomElement({
// 常規(guī) Vue 組件選項(xiàng)
})
// 注冊(cè)自定義元素。
// 注冊(cè)完成后,此頁面上的所有 `<my-vue-element>` 標(biāo)簽
// 都將將升級(jí)。
customElements.define('my-vue-element', MyVueElement)
此 API 允許開發(fā)者們創(chuàng)建由 Vue 驅(qū)動(dòng)的 UI 組件庫。這些庫可以支持任何框架選項(xiàng),甚至能夠在無框架情況下正常使用。
9總結(jié)
以上諸多特性,最讓我感興趣的是setup script,此語法使單個(gè)文件組件更簡(jiǎn)單!只需要給 script 標(biāo)簽添加一個(gè) setup 屬性,那么整個(gè) script 就直接會(huì)變成setup函數(shù),所有頂級(jí)變量、函數(shù),均會(huì)自動(dòng)暴露給模板使用(無需再一個(gè)個(gè) return了),開發(fā)效率將大大的提高!
以至于連尤大也在微博上呼吁大家:“如果你能用Vue3卻還在用 Options API,現(xiàn)在有了< 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正式發(fā)布,script setup + TS + Volar = 真香
