Vue3 window

  • Performance: Better Performance than Vue 2.0.
  • Tree Shaking Support: You can “clip” useless modules and package only the ones you need.
  • Composition API: Composition API
  • Girl: Fragment, Teleport, Suspense
  • Better TypeScript Support: Better Ts support
  • Custom Renderer API: Exposes Custom rendering apis

For small projects, the perception of the above highlights is not obvious. These highlights are especially prominent in large projects with complex business scenarios, which will bring better experience and greatly improve production efficiency.

In fact, the above highlights are some of the official highlights listed by THE UNIVERSITY of Utah during its live broadcast. Check out the details here

Here are some of the major changes to VUE3

Some major changes to VU3

Global API

Call createApp returns an application instance

import { createApp } from 'vue'

createApp(App).use(router).use(store).mount('#app')
Copy the code
2. X global API 3. X Instance API (app)
Vue.config app.config
Vue.config.productionTip remove
Vue.config.ignoredElements app.config.isCustomElement
Vue.component app.component
Vue.directive app.directive
Vue.mixin app.mixin
Vue.use app.use
Vue.prototype app.config.globalProperties

Global API Treeshaking

The usage Vue2. X

Import Vue from 'Vue' vue.nexttick (() => {// something DOM related})Copy the code

In Vue 3, both the global and internal apis have been refactored to take tree-shaking support into account. As a result, the global API can now only be accessed as named exports of ES module builds.

Import {nextTick} from 'vue' nextTick(() => {// something DOM related})Copy the code

These global apis in Vue 2.x are affected by this change:

  • Vue.nextTick
  • Ue. Observable (replaced by ue. Reactive)
  • Vue.version
  • Vue.compile (full build only)
  • Vue.set (build only)
  • Vue.delete (build only)

Pieces & $attrs

Now $attrs contains all the attributes passed to the component, including class and style

One thing to note is that in 3.x, multiple root nodes are now supported. When defining multiple root nodes, you need to explicitly define where the attribute should be distributed

<template> <header>... </header> <main v-bind="$attrs">... </main> <footer>... </footer> </template>Copy the code

Custom instruction

The API has the following changes, the hook function parameters do not change

  • The bind – beforeMount
  • He inserted – mounted
  • BeforeUpdate: New! This is called before the element itself is updated, much like a component lifecycle hook.
  • Update → Remove! There are too many similarities to update, so this is redundant, please use updated instead.
  • ComponentUpdated – updated
  • BeforeUnmount: New! Similar to a component lifecycle hook, it is called before an element is unloaded.
  • unbind -> unmounted

The Data definition

The data option has been standardized to accept only functions that return object

Mixin and extend merge data as shallow merge

Writing mixins is not recommended in Vue3, using the Composition API instead.

emits Option

The child component fires the parent component event by passing emits: []

<template> <div> <p>{{ text }}</p> <button v-on:click="$emit('accepted')">OK</button> </div> </template> <script> export  default { props: ['text'], emits: ['accepted'], setup (props, context) { onMounted(() => { context.emit('accepted') }) } } </script>Copy the code

Event apis

The on, ON, ON, off, and once instance methods have been removed and the application instance no longer implements the event-triggering interface. That is, the busonce instance method cannot be removed directly, and the application instance no longer implements the event-triggering interface. That is, the bus once instance method cannot be removed directly, and the application instance no longer implements the event triggering interface. It is no longer possible to communicate directly between busEMIT and $ON components. Mitt third-party library is officially recommended. Similar API, still familiar flavor ~

import mitt from 'mitt'
const emitter = mitt()
// ...
emitter.emit('trigger', params)
// ...
emitter.on('trigger', callback)
// ...
emitter.off('trigger', callback)
Copy the code

Functional components *

Mainly stateless component differences:

  • The functional attribute in<template>Remove the
  • Listeners are now delivered as part of $attrs and can be removed

However, in Vue 3, the performance of stateful components has improved to a negligible level.

v-model

  • Incompatible: V-Model Prop and event default names have been changed when used for custom components:
  • Prop: value -> modelValue;
  • Event: input -> update:modelValue;
  • Incompatible: v-bind’s.sync modifier and component’s model option have been removed and v-model can be used instead;
  • New: Bidirectional binding with multiple V-Models on the same component is now possible;
  • New: V-Model modifiers can now be customized.
<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" /> <! -- is short for:  --> <ChildComponent :title="pageTitle" @update:title="pageTitle = $event" :content="pageContent" @update:content="pageContent = $event" />Copy the code

Comparison of v-IF and V-for priorities

When both are applied to the same element, v-if has a higher priority than V-for. It is strongly recommended not to use both on the same element

Custom element interactions

  • Incompatible: Custom element whitelists are now executed during template compilation and should be configured through compiler options rather than runtime configuration.
  • Incompatible: Specific is prop usage is limited to reserved<component> The tag.
  • New: New V-IS directives to support 2.x use cases where V-IS is used on native elements to handle native HTML parsing constraints.

Click here for more details of the changes

Replace the config. IgnoredElements and vue – loader compilerOptions (using build steps) or app. Config. IsCustomElement (using dynamic template compilation)

Change all non-< Component > tags and is usage to

(for SFC templates) or V-is (for DOM templates).

key attribute

  • New: Branch keys for V-if/V-else/V-else -if are no longer required, as Vue now automatically generates unique keys.
    • Incompatibility: If you supply keys manually, each branch must use a unique key. You cannot force reuse of branches by deliberately using the same key.
  • Not compatible with:<template v-for>The key should be set in<template>Tag (not set on its child nodes).

It is not recommended to use key attributes in branches of V-if/V-else/V-else -if

Key modifier

  • Incompatible: The use of numbers (i.e. key codes) as V-ON modifiers is no longer supported
  • Incompatible: Config.keycodes are no longer supported

It is now recommended to use the kebab-cased (dash) case name for any key to be used as a modifier.

Access this in prop’s default function

Factory functions that generate prop defaults can no longer access this.

Alternatives:

Pass the original prop received by the component as an argument to the default function;

The injection API can be used in default functions.

Render function API

  • H is now imported globally instead of being passed as an argument to the render function
  • Render function parameters changed to be more consistent between stateful components and function components
  • Vnode now has a flat prop structure

The render function no longer takes any arguments and will be used primarily inside the setup() function

Import {h} from 'Vue' export default {render() {return h('div')}}Copy the code

In 3.x, the entire VNode props structure is flat

// 3. X syntax {class: ['button', 'is-bank statements '], style: {color: '#34495E'}, id: 'submit', innerHTML: ', onClick: statements submitForm, key: 'submit-button' }Copy the code

About Devtools

Local development requires the latest vuE-Tools beta

For Chrome: Chrome Store installation

Note that vue-tools is still not displayed after the installation. Please disable vue-tool for the local stable version, which will cause conflicts.

Features removed from vue3

Remove $children

The $children instance property has been removed from Vue 3.0 and is no longer supported. If you need access to child component instances, $refs is recommended

The filter

As of Vue 3.0, filters have been removed and are no longer supported.

If the component defines filters filters internally, it is recommended that method calls or evaluate properties replace them

If the global filter is defined, it is suggested that through global properties used in all of the components it app. Config. GlobalProperties. $filters. Note that this approach can only be used in methods, not computed properties, because the latter makes sense only if defined in the context of a single component.

V – on. Native has been removed

All V-ON binding events are no longer supported. Native modifier

Inline template Attribute

Support for inline features has been removed.

Remove $listeners

The $Listeners object has been removed from Vue 3.

Composition API

This is one of the biggest highlights of VUE3, which can be a good substitute for mixin of VUe2. X, and achieve more flexible and side-effectless reuse code with functional programming thought. This is especially useful in complex business scenarios with large components, where splitting large components is much easier.

However, Vue3 also supports the original Options API, and can even be mixed with the composite API. For some small projects, you can use the Options API in combination with other new vue3 features.

setup

The setup function is a new component option. As an entry point for using the Composition API within components.

Create the component instance, initialize props, and then call the setup function. From a lifecycle hook perspective, it is called before the beforeCreate hook.

Setup takes two arguments, the first being the props object and the second context object, context.

Setup internal context can only access attrs, slots, emit, and not any other properties declared in the component — local state, computed properties, or methods.

Ref and Reactive are two reactive apis that convert declared variables to reactive.

Ref takes a parameter value () and returns a responsive and mutable ref object. Ref is used internally with.value, but not in templates.

reactive

If Setup returns an object, the properties of the object will be incorporated into the rendering context of the component template.

<template> <div>{{ count }} {{ object.foo }}</div> </template> <script> import { ref, reactive } from 'vue' export default { props: { name: String, }, setup(props, context) { const count = ref(0) const object = reactive({ foo: 'bar' }) watchEffect(() => { console.log(`name is: ` + props.name) console.log(`attrs is: ` + context.attrs) console.log(`slots is: ` + context.slots) console.log(`emit is: '+ context.emit)}) // Expose to template return {count, object,}},} </script>Copy the code

Setup can also return a function that uses reactive data in the scope of the current setup function

import { h, ref, reactive } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const object = reactive({ foo: 'bar' })

    return () => h('div', [count.value, object.foo])
  },
}
Copy the code

Note that in the TS notation, you need to use defineComponent to get type inference for arguments passed to setup()

export default defineComponent({
    setup(props, context) {}
    ...
})
Copy the code

watch & watchEffect

The watch usage is the same as vue2, except that it supports listening to multiple data sources.

watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
  /* ... */
})
Copy the code

WatchEffect executes a function passed in immediately, traces its dependencies responsively, and rerunts the function when its dependencies change. The difference between the two is:

  • WatchEffect does not need to specify a listening attribute. It automatically collects dependencies. Whenever a callback references a responsive attribute, the callback will be executed when the attribute changes, whereas watch can only listen for the specified attribute (v3 can specify multiple attributes at the same time).
  • Watch can get new and old values (pre-update values), but watchEffect can’t.
  • WatchEffect, if it exists, is executed once at component initialization to collect dependencies (as with computed), and the callback is executed again when the collected dependencies change, which Watch doesn’t need because it specified the dependencies in the first place.

Lifecycle hook functions

To register lifecycle hooks, import the onXXX family of functions directly:

import { onMounted, onUpdated, onUnmounted } from 'vue' const MyComponent = { setup() { onMounted(() => { console.log('mounted! ') }) onUpdated(() => { console.log('updated! ') }) onUnmounted(() => { console.log('unmounted! ')})}},Copy the code

These lifecycle hook registration functions can only be used synchronously during setup() because they rely on internal global state to locate the current component instance (the one that is calling setup()), and not calling these functions on the current component will throw an error.

The component instance context is also set during lifecycle hook synchronization execution, so listeners and computational state created synchronously inside the lifecycle hook are automatically removed when the component is unloaded.

  • A composite API corresponding to the 2.x release lifecycle
    • BeforeCreate -> Use setup()
    • Created -> Setup ()
    • beforeMount -> onBeforeMount
    • mounted -> onMounted
    • beforeUpdate -> onBeforeUpdate
    • updated -> onUpdated
    • beforeDestroy -> onBeforeUnmount
    • destroyed -> onUnmounted
    • errorCaptured -> onErrorCaptured
    • renderTracked -> onRenderTracked
    • renderTriggered -> onRenderTriggered

These will not do the detailed expansion, not clear can refer to the official document.

The final summary

The above is a personal filter of some of the changes vue3 has made to vue2.x, as well as some of the key new features and apis. There must be some omissions. To learn the use of VUe3 in detail, I still suggest looking at the VUe3 documentation, which is just to throw some light on the topic.

Use the new instead of the old. Vue3 does make some changes on the basis of VUe2. X, improving many aspects, and to some extent solving some pain points of vuE2. New projects can be directly built with VUe3 + TS + VUE-Router + VUex, with the use of Element Plus component library. Currently, Vite is still being updated and not stable enough, so it is not recommended to use it.

However, if the project is not due to some inevitable issues and pain points that can be well addressed by updating to VUE3, then there is no need to migrate. Especially in the stage of stable production. The old project migration can wait for the transition version of vue2.7 migration

Some tips to help you learn & understand VuE3:

Official Chinese document

Composition API official introduction

Some articles that I think are good:

Juejin. Cn/post / 684490…

Juejin. Cn/post / 684490…

Juejin. Cn/post / 684490…

Juejin. Cn/post / 685855…

Juejin. Cn/post / 690317…

Some projects and demos that I think are good:

Github.com/anncwb/vue-…

Github.com/githyw/colu…