Vue version 3.2 includes many important new features and performance improvements, but does not include major changes.
Vue 3.2 original link
The main updates are as follows:
1. New single file component function
< script setup > is a compile time syntax sugar, which can greatly improve work efficiency when using Composition API in SFC.
< style > v-bind enables component state driven dynamic CSS values in SFC tags< style>
At first vue3 0 exposed variables must be return ed before they can be used in the 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>
vue3. In 2, you only need to add the setup attribute on the script tag. During the compilation of the component, the code runs up and down in the setup() function. All ES module exports are considered values exposed to the context and are included in the setup() return object.
<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>
In fact, script setup is equivalent to running the code in the setup function during compilation, and then defining the exported variables into the context and including them in the returned objects.
style v-bind uses the following:
<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>
2. Web components
Web Components are a different set of technologies that allow you to create reusable custom elements -- encapsulate their functionality with the rest of the code -- and use them in your web applications.
Vue 3.2 introduces a new way to easily create native custom elements using Vue component API s: 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)
Learn more about web components:
Web_Components
web-components-examples
3. Performance improvement
It is mainly reflected in the improvement of interface rendering speed and the reduction of memory usage:
- More efficient ref implementation (about 260% read speed / about 50% write speed)
- About 40% faster dependency tracking
- Memory usage reduced by about 17%
The template compiler has also been improved: - The speed of creating ordinary element VNode is increased by about 200%
Finally, a new v-memo instruction provides the ability to remember part of the template tree. A v-memo allows Vue to skip virtual DOM version comparison and create new virtual nodes. Although rarely required, it provides an escape pod to squeeze out maximum performance in some cases (such as large v-for lists).
4. Server rendering
The package in 3.2 now provides an ES module build, which is also related to node JS built-in module separation. This enables bundling and leveraging non node JS runtime (such as CloudFlare Workers or Service Workers) becomes possible@ vue/server-renderer
5. Effect range API
3.2 a new Effect Scope API (effectScope, getCurrentScope, onScopeDispose, etc.) is introduced to directly control the processing time of reactivity effects (calculation and observer). It makes it easier to leverage Vue's responsive API outside the component context, and also unlocks some advanced use cases inside the component.
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
6. Some attribute usage changes
(1) useContext API deprecated
Originally, the API can be used to obtain the context information of components, including the communication data and methods of parent-child components such as attrs, slots, emit and expose.
The API will be deleted after version 3.2. The data in the context will be replaced by the new useSlots and useattrs APIs.
useAttrs:
// Import useAttrs components import { useAttrs } from "vue"; // Get attrs const attrs = useAttrs(); // attrs is an object. Like props, you need to get the corresponding single attr through key console.log(attrs.msg);
useSlots:
import { defineComponent, useSlots } from "vue"; const ChildTSX = defineComponent({ setup() { // Get slot data const slots = useSlots(); // Rendering Components return () => ( <div> // Render default slot <p>{slots.default ? slots.default() : ""}</p> // Render named slot <p>{slots.msg ? slots.msg() : ""}</p> </div> ); }, }); export default ChildTSX;
defineExpose:
Use example of original exposure:
// Import useContext component import { useContext } from "vue"; // Enable expose component const { expose } = useContext(); // Define the data you want to provide to the parent component const msg: string = "Hello World!"; // Only when the exposed data is displayed can it be obtained in the parent component expose({ msg, });
Exposure through defineExpose after version 3.2
// Import defineExpose component import { defineExpose } from "vue"; // Define data const msg: string = "Hello World!"; // Expose to parent component defineExpose({ msg, });
defineEmits:
// Import defineEmits component import { defineEmits } from "vue"; // Get emit const emit = defineEmits(["say-hi", "chang-name"]); // Call emit to say hello emit("say-hi", "Hello!"); // Call emit to rename emit("chang-name", "Tom");
Add withDefaults:
import { defineProps, withDefaults } from "vue"; withDefaults( defineProps<{ size?: number; labels?: string[]; }>(), { size: 3, labels: () => ["default label"], } );
(2) Top level await support
await can be used directly without cooperating with async. In this case, the component setup will automatically become async setup
<script setup lang="ts"> const post = await fetch(`/api/post/1`).then((r) => r.json()); </script>
The way it is converted into a standard component is:
<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>