It has been some time since the Vue team released the V3.0 version. As a major update, Vue3 brings a new development experience and improved performance. Although the surrounding ecological plug-ins, such as Vue-Router and Vuex, are still not perfect, many users and enterprises are using them in the production environment. Mainstream UI component libraries like Ant-Design Vue, ElementUI, Vant, etc., have also released stable versions adapted to Vue3. That said, it’s not too late to get started on Vue3, and this article will introduce you to new features and major updates.

Refactor the entire framework with TypeScript

TypeScript is a superset of JavaScript that provides support for ES6 and can be compiled to pure JavaScript. This update includes responsive systems, template compilation, and vDom. All code has been rewritten in TypeScript to improve performance and reduce volume. But for those of you who aren’t familiar with typeScript and want to read the source code, there may be a cost.

Use Proxy to implement responsiveness

In order to achieve better performance and deep listening, Proxy is adopted to implement response, which makes up for the deficiency of object.defineProperty in Vue 2.x:

  • Cannot monitor the add or delete actions of attributes
  • Cannot monitor array subscript changes and length changes
  • Map, Set, WeakMap, and WeakSet are not supported

In VUe2.x, if the Data hierarchy is deep, there will be obvious lag when using defineProperty. Proxy avoids this problem well. The Proxy can listen in depth for better performance, and it can also listen for array changes, but the Proxy implementation is responsive and not compatible with all browsers, nor does it support Polyfill.

Source volume optimization, compilation optimization

This update saves a lot of volume by removing some of the less popular features such as filters, inline-templates, and so on. It also introduces Tree-shaking technology to reduce the volume after packaging; On the compile side, the static nodes and data taken from the template are promoted out of the rendering function, avoiding the need to recreate these objects each time rendering, which greatly improves memory usage and reduces garbage collection frequency.

New syntax API

If you’re a developer of Vue2.x, you’ve probably experienced this discomfort when developing larger components, so if you want to reuse parts of your component code and want better typeScript support, The Composition API introduced by Vue 3 solves this problem; Optimize the development experience brought by complex logic in Vue 2.x, so that developers can better optimize logic and logic reuse; New unified entry setup, and fully replaced lifecycle hooks.

Supports multiple fragments. – Fragment

Create a component in vue2.x that requires each template to have a root node, otherwise it will prompt an exception, so we have to do this:

<template>
  <div>
  	<p>Vue2.x</p>
  	<p>Vue3</p>
  </div>
</template>
Copy the code

This can be addressed by introducing third-party libraries such as Vue-fragments, but in Vue3 we can use multiple fragments directly during development:

<template>
  <p>Vue2.x</p>
  <p>Vue3</p>
</template>
Copy the code

It not only improves the development experience, but also eliminates many unnecessary elements.

Portal – Teleport

Teleport can be used to mount your component to the bottom of a specified element. There are many common usage scenarios. In some components with more nested layers, for the sake of component maintenance, the style and DOM can be detached from the nested layer and mounted to the bottom of the specified element. Note that although they are not nested in the original component hierarchy, they still belong to the parent component relationship. Teleport takes two parameters:

  • To: a valid HTML element, or its ID, class selector;
  • Disabled: Indicates whether to disable the function.

New Lifecyle Hooks

Vue 3’s new lifecycle hook can only be used in component instances of setup, and will report an error if called elsewhere. Compare this to Vue 2.x’s lifecycle.

Vue2.x Vue3
beforeCreate setup
created setup
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeDestroy onBeforeUnmount
destroyed onUnmounted
errorCaptured onErrorCaptured

Vue 3 also adds two new hook functions: onRenderTracked: checks which Reactive object property is tracked or an REF is tracked as a dependency. When the Render function is called, it checks which responsive data is being collected for dependencies. OnRenderTriggered: When an Update operation is performed, checks which reactive data causes the component to be rerendered.

The setup-Composition API gate

Setup serves as the gateway to the Composition API. All but a few helper functions are required to use the Composition API in Setup. Setup is called after you initialize the Props. Setup is called before beforeCreate.

The setup is defined

function setup(props: Data, context: SetupContext) :Data

interface Data {
    [key: string]: unknown
}

interface SetupContext {
  attrs: Data
  slots: Slots
  emit: (event: string. args: unknown[]) = > void
}
Copy the code

New slot instruction V-slot

In fact, this directive was introduced in Vue 2.6 to indicate named slots and default slots, but the slot-scope hierarchy can’t clearly reflect which slot the scope comes from, so Vue 3 uses the directive parameter to indicate the slot name.

<! -- default slot -->
<div v-slot="{ msg }">
    {{ msg }}
</div>

<! -- named slot -->
<div>
    <template v-slot:one="{msg}">  {{ msg }} </template> 
</div>
Copy the code

Dynamic slot name

Dynamic instruction parameters can also be used on V-slot to define the dynamic slot name:

<div>
    <template v-slot:[slotName] ></template>
</div>
Copy the code

Abbreviation for slot directive

Similar to v-bind and V-ON, the abbreviation only works if there are arguments, which means that #= cannot be used for v-slots without arguments. For default slots, #default can be used instead of V-slot.

<! - for - >
<div>
  <template #header="{ msg }"></template>
  <template #footer></template>
</div>
Copy the code