vue3.2版本新特性


Vue 3.2 版本包括許多重要的新功能和性能改進,但並不包含重大更改。
Vue 3.2 原文鏈接

https://blog.vuejs.org/posts/vue-3.2.html

主要更新如下:

1. 新的單文件組件功能
<script setup> 是一種編譯時語法糖,可在 SFC 內使用 Composition API 時極大地提升工作效率。
<style> v-bind 在 SFC 標簽中啟用組件狀態驅動的動態 CSS 值。<style>

起初 vue3.0 暴露變量必須 return 出來,template中才能使用

<script>
import Foo from './Foo.vue'
import Bar from './Bar.vue'
export default {
setup (props) {
console.log(props)
return {
ok: Math.random(),
Foo,
Bar
}
}
}
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vue3.2 中 只需要在 script 標簽上加上 setup 屬性,組件在編譯的過程中代碼運行的上下是 setup() 函數中。所有ES模塊導出都被認為是暴露給上下文的值,並包含在 setup() 返回對象中。

<template>
<Foo/>
<Bar/>
<component :is="ok ? Foo : Bar"/>
</template>

<script setup="props">
export { default as Foo } from './Foo.vue'
export { default as Bar } from './Bar.vue'
export const ok = Math.random()
console.log(props)
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
其實 script setup 就相當於在編譯運行是把代碼放到了 setup 函數中運行,然后把導出的變量定義到上下文中,並包含在返回的對象中。

style v-bind 使用如下:

<template>
<button @click="color = color === 'red' ? 'green' : 'red'"> Color is: {{ color }} </button>
</template>

<script setup>
import { ref } from 'vue'
export const color = ref('red')
</script>

<style scoped>
button { color: v-bind(color);}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
2. 網頁組件
Web Components 是一套不同的技術,允許您創建可重用的自定義元素——將它們的功能與代碼的其余部分封裝在一起——並在您的 Web 應用程序中使用它們。

Vue 3.2 引入了一種使用 Vue 組件 API 輕松創建原生自定義元素的新方法:defineCustomElement

import { defineCustomElement } from 'vue'

const MyVueElement = defineCustomElement({
// normal Vue component options here
})

// Register the custom element.
// After registration, all `<my-vue-element>` tags
// on the page will be upgraded.
customElements.define('my-vue-element', MyVueElement)
1
2
3
4
5
6
7
8
9
10
更多網頁組件學習:
Web_Components
web-components-examples

3. 性能改進
主要表現在界面渲染速度的提升和內存使用減少上:

更高效的 ref 實現(約 260% 的讀取速度/約 50% 的寫入速度)
約 40% 更快的依賴跟蹤
內存使用量減少約 17%
模板編譯器也得到了一些改進:
創建普通元素 VNode 的速度提高了約 200%
最后,有一個新v-memo指令提供了記憶模板樹的一部分的能力。一v-memo允許Vue跳過虛擬DOM版本比較,創建新的虛擬節點。雖然很少需要,但它提供了一個逃生艙,以在某些情況下(例如大型v-for列表)擠出最大性能。

4.服務端渲染
3.2 中的包現在提供了一個 ES 模塊構建,它也與 Node.js 內置模塊分離。這使得捆綁和利用非 Node.js 運行時(例如 CloudFlare Workers 或 Service Workers)成為可能。@vue/server-renderer

@vue/server-renderer

5. 效果范圍 API
3.2 引入了一個新的 Effect Scope API (effectScope、getCurrentScope、onScopeDispose等),用於直接控制反應性效果(計算和觀察者)的處理時間。它可以更輕松地在組件上下文之外利用 Vue 的響應式 API,並且還解鎖了組件內部的一些高級用例。


function effectScope(detached?: boolean): EffectScope
interface EffectScope {
run<T>(fn: () => T): T | undefined // undefined if scope is inactive
stop(): void
}


const scope = effectScope()
scope.run(() => {
const doubled = computed(() => counter.value * 2)

watch(doubled, () => console.log(doubled.value))

watchEffect(() => console.log('Count: ', doubled.value))
})

// to dispose all effects in the scope
scope.stop()


function getCurrentScope(): EffectScope | undefined

function onScopeDispose(fn: () => void): void
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
6. 一些屬性使用變更
(1)useContext API 被棄用
在原先,可以通過該 API 來獲取組件的上下文信息,包含了 attrs 、slots 、emit、expose 等父子組件通信數據和方法。
該 API 將在 3.2 版本之后刪除,context 里面的數據,會用新的 useSlots 和 useAttrs API 來代替。

useAttrs:

// 導入 useAttrs 組件
import { useAttrs } from "vue";

// 獲取 attrs
const attrs = useAttrs();

// attrs是個對象,和 props 一樣,需要通過 key 來得到對應的單個 attr
console.log(attrs.msg);
1
2
3
4
5
6
7
8
useSlots:

import { defineComponent, useSlots } from "vue";

const ChildTSX = defineComponent({
setup() {
// 獲取插槽數據
const slots = useSlots();

// 渲染組件
return () => (
<div>
// 渲染默認插槽
<p>{slots.default ? slots.default() : ""}</p>
// 渲染命名插槽
<p>{slots.msg ? slots.msg() : ""}</p>
</div>
);
},
});

export default ChildTSX;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
defineExpose:

原expose使用示例:

// 導入 useContext 組件
import { useContext } from "vue";

// 啟用expose組件
const { expose } = useContext();

// 定義一個想提供給父組件拿到的數據
const msg: string = "Hello World!";

// 顯示暴露的數據,才可以在父組件拿到
expose({
msg,
});
1
2
3
4
5
6
7
8
9
10
11
12
13
3.2 版本后通過defineExpose暴露

// 導入 defineExpose 組件
import { defineExpose } from "vue";

// 定義數據
const msg: string = "Hello World!";

// 暴露給父組件
defineExpose({
msg,
});
1
2
3
4
5
6
7
8
9
10
defineEmits:

// 導入 defineEmits 組件
import { defineEmits } from "vue";

// 獲取 emit
const emit = defineEmits(["say-hi", "chang-name"]);

// 調用 emit 打招呼
emit("say-hi", "Hello!");

// 調用 emit 改名
emit("chang-name", "Tom");
1
2
3
4
5
6
7
8
9
10
11
新增withDefaults:

import { defineProps, withDefaults } from "vue";

withDefaults(
defineProps<{
size?: number;
labels?: string[];
}>(),
{
size: 3,
labels: () => ["default label"],
}
);
1
2
3
4
5
6
7
8
9
10
11
12
(2) 頂級 await 的支持
不必再配合 async 就可以直接使用 await 了,這種情況下,組件的 setup 會自動變成 async setup

<script setup lang="ts">
const post = await fetch(`/api/post/1`).then((r) => r.json());
</script>
1
2
3
它轉換成標准組件的寫法就是:

<script lang="ts">
import { defineComponent, withAsyncContext } from "vue";

export default defineComponent({
async setup() {
const post = await withAsyncContext(
fetch(`/api/post/1`).then((r) => r.json())
);

return {
post,
};
},
});
</script>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM