What is new in Vue 3.2
Foreword
In the early morning of 8.10, You Yuxi officially announced the official release of Vue 3.2 on the Weibo platform:
This release contains a number of important new features and performance improvements, but does not involve any breaking changes. This article mainly introduces some relatively important new features of Vue3.2. For more information, please refer to the official documentation!
New SFC function
Two features regarding single-file components (SFCs, ie .vue files) have officially graduated from experimental status and are now available in stable versions :
<script setup>
Is a compile-time syntactic sugar that greatly improves the developer experience when using the Composition API in SFC.<style> v-bind
Used to enable component state driven dynamic CSS values in SFC<style>
tags.
1. <script setup>
In <script setup>
, we don't have to declare export defaultand setupmethod, this way of writing will automatically expose all top-level variables and functions to the template (template) use . Let's first use an example to compare script setupthe difference in writing before and after, and intuitively feel setupthe convenience brought to us:
//Writing before script setup
<template>
<div>
<div>boating in the waves</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 new feature script setup");
return { message };
},
});
</script>
//Writing of script setup
<template>
<div>
<div>boating in the waves</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 new feature script setup");
</script>
From the above example, the <script setup>syntax omits the registration step of the component Card and the statement of the return variable message, which makes the code more compact. There are also some details and precautions about <script setup>the use of , which I will introduce in detail in the next article.
2. <style> v-bind
An interesting new feature, through this directive, the CSS flexibility of Vue SFC will be greatly improved. This directive works with <script setup>, and supports JavaScript expressions (must be enclosed in quotes).
<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>
Click the button to change the color
value of or , and you can see that the page style also changes responsively. fontSize
The idea is that the custom property will be applied to the root element of the component via inline styles, and will be updated in response to changes in value.
v-memo
Version 3.2 brings a series of major performance improvements to Vue's reactive system , including:
- More efficient ref implementation (~260% faster read, ~50% faster write)
- ~40% faster dependency tracking
- ~17% reduction in memory usage
The new version also provides a new v-memo
instruction that can realize the memory function of part of the template tree. When v-memo
hit, not only allows Vue to skip the virtual DOM diff, it even skips the new VNode creation step entirely. Although this directive is not used frequently, it provides an escape hatch to obtain maximum performance in certain situations (such as dealing with large v-for
lists ).
<div v-for="user of users" :key="user.id" v-memo="[user.name]">
{{ user.name }}
</div>
Using this example v-memo
, the dummy element will not be recreated, and the previous element will be reused unless v-memothe conditions (username here) change. This might seem like a small improvement, but if you're rendering a lot of elements, it's actually a huge improvement in performance.
In fact v-memo,
a set of conditions can be accepted, see the following example:
<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>
It will be updated if user.name
or selectedUserId
changes at this point. div
new ref syntactic sugar (experimental)
$ref()
Avoiding the need to use when updating the ref value .value
can make the code more compact! See the example below:
<template>
<input type="number" v-model="count"> * 5€
<h1>{{ total }}</h1>
</template>
<script setup>
let count = $ref(0)
let total = $computed(() => count * 5)
</script>
⚠️Note: This is still an experimental feature, so use it with caution as it may change in the future. The proposal also introduces other new syntactic sugars, including $computed(), $fromRefs()and $raw().
Expose API
Vue 3.2 added a new Expose APIto define what a component exposes. Expose APIThe idea is to provide a composable API like expose({ ...publicMembers })
this that component authors can setup()
use in , to fine-tune what is exposed publicly to other components.
In the following example, the component can only expose its toggle
functions, not its collapsed
variables.
<template>
<input type="number" v-model="count"> * 5€
<h1>{{ total }}</h1>
</template>
<script setup>
let count = $ref(0)
let total = $computed(() => count * 5)
</script>
Note that all $
instance properties are automatically exposed , so Collapse
the used components can access them $props
, $slots
among others. This can also be done when used <script setup>
by calling a function.defineExpose()
When you are encapsulating components, if you think refthat there is too much exposed content in the , you might as well use Expose API
it to constrain the output!
Effect Scope API
The Vue 3.2 version introduced new Effect scope API
for creating an effect Scope
object that captures reactive effects created in it (such as computed
or watchers
) so that they can be put together and handled easily. It makes it easier to use Vue's reactive API outside the context of a component, while also unlocking a variety of advanced use cases within a component. Effect scope
is a high-level API, mainly used by library authors.
We know that watch
, watchEffect
, computed
etc. are all bound to a specific component instance, and will be automatically destroyed by Vue when the component is destroyed. This ensures that the application has no memory leaks. But if you want to use these functions outside of components, for example in a library you're writing, you need to handle them manually, see the following example:
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
.prop and .attr modifiers
- .
prop
: is used to force binding of DOM properties (property) - .
attr
: is used to force binding of DOM attributes (attribute)
v-bind is bound to the attribute of the DOM node by default. .prop
After using the modifier, the set custom attribute will not be displayed in the rendered HTML tag, but the .attr
modifier is just the opposite!
.prop
Modifier usage:
- Store variables with custom properties to avoid exposing data
- Prevent polluting HTML structure
<input id="input" type="foo" value="11" :data.prop="inputData"></input>// HTML tag structure after rendering <input id="input" type="foo" value ="11"></input>
After seeing its purpose, you will know that if you don't want your attribute to be displayed in the html tag, use the .prop
modifier!
In addition these two modifiers have shorthand syntax:
<a :title.prop="firstTabTooltip" :aria-selected.attr="isFirstTabSelected">First tab</a><!-- shorthand--><a .title="firstTabTooltip" ^aria-selected="isFirstTabSelected ">First tab</a>
Web Components
Vue 3.2 introduces new defineCustomElement
methods to easily create native custom elements using the Vue components API:
import { defineCustomElement } from 'vue'const MyVueElement = defineCustomElement({ // regular Vue component options})// Register custom element. // After registration, all `<my-vue-element>` tags on this page // will be upgraded.
customElements.define('my-vue-element', MyVueElement)
This API allows developers to create a library of UI components powered by Vue. These libraries can support any framework option and even work without a framework.
Summarize
Of all the features above, what interests me the most is setup script
that this syntax makes single-file components simpler! script
Just add an setup
attribute to the tag, then the scriptwhole will become a setupfunction directly, and all top-level variables and functions will be automatically exposed to the template for use (no need to return one by one), and the development efficiency will be greatly improved!
Even You Da also called on everyone on Weibo: "If you can use Vue3 but still use the Options API, now that you have <script setup>, there is no reason not to change the Composition API."