【Vuejs】1072- Vue 3.2 有哪些新變化?

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 defaultsetup方法,這種寫法會自動將所有頂級變量、函數,均會自動暴露給模板(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.nameselectedUserId發生變化,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 component
    expose({ 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,主要供庫作者使用。

我們知道watchwatchEffect,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"></i
nput>

看了它的用途就知道,如果你不想你的屬性顯示在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參考資料


本文分享自微信公衆號 - 前端自習課(FE-study)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章