Original text: my blog garden article

Public account: wechat search web full stack advanced; Take more dry goods

I. Links to official Chinese documents

https://vue3js.cn/docs/zh/

Second, the opening

  • Vue3.0 was officially released on the evening of September 18thVue3.0 betaVersion;
  • betaVersion of the meanvue3.0The opening is officially put into the project; We can be happy to learn (front-end new technology you continue to give, I also learn to move… Because to live to eat!! ;
  • The front-end technology ecosystem has been constantly updated, many people think Alexander can’t learn; But if you can’t move, you can stop learning…0.0; Learn not to move also have to learn, otherwise adapt to their own will only be eliminated

Iii. Suggestions for vue2.0 project

To quote the author of the official document:

Tip:

We are still working on a dedicated migration version of Vue 3 that is compatible with the behavior of Vue 2 and incompatible with runtime warnings. If you plan to migrate a very important Vue 2 application, we strongly recommend that you wait for the migration to complete for a smoother experience.

The author’s current meaning is: Upgrading to VUe3.0 is strongly not recommended for vue2.0 projects; Due to the current beta version and existing frameworks and plug-ins, vue3.0 syntax is not well supported and compatible; So there must be a lot of unexpected problems; For those who are eager to upgrade VUe3.0, they can only wait for the official compatible version to be developed and then migrate. After all, online projects are no joke, and a bug could be a major loss. This pot home without the basic back of the mine does not move…

Introduce four,

What does Vue3 bring? Reference to:Public number: front – end morning reading class article

Please refer to:Official Chinese document link

  • faster
    • To reconstruct theVirtual DOM
      • Flag static content and distinguish dynamic content
      • Only when the updatediffDynamic part
    • To reconstruct theTwo-way data binding
      • Object.defineProperty() --> Proxy API
      • ProxyFor complex data structures, the loop recursion is reduced. Initial render loop recursion is very performance intensive;
      • ProxyFor the array mutation method (will modify the original array), no longer need to use the array native method rewrite, processing
      • Grammar is better thandefinePropertyMuch simpler, just listen on a property;
    • Event caching
      • vue2For binding events, a brand new one is regenerated each time it is firedfunctionTo update;
      • Vue3, provides an event cache objectcacheHandlerswhencacheHandlersWhen turned on, the compilation automatically generates an inline function, turning it into a static node so that when the event fires again, it calls the cached event callback method directly without recreating the function
  • Smaller (Tree shakingSupport)
    • In short: Don’t pack everything, just what you needapi; For big projects you’ll notice that hot loading, initial rendering has improved a lot
    • Greatly reduce the development of redundant code, improve the speed of compilation
  • Easier to maintain
    • Vue3fromFlowMigration toTypeScript
      • In the case of collaborative development of multiple people, yesTypeScriptAfter the acid cool you will ridicule, why did not appear earlyTypeScript
    • The code directory structure follows Monorepo
      • Core point: The code is broken up into small modules, and developers mostly work in a few folders and only build their own modules; Instead of compiling the entire project
  • New features and featuresComposition API
    • Never mind getting more like React-hook; After all, the advantages of others are worth learning from themselves;
    • Composition APIFunctional development, greatly improve the reuse of components, business logic; Highly decoupled; Improve code quality and development efficiency; Reduce code size
  • Improve development efficiencyviteFor now, of courseviteThe features aren’t powerful or stable enough, but Utah makes it workvue3Official build tool, sure U will perfect it; Free choicewebpackorvite)
    • viteIn the development environment based on browser nativeES importsDevelopment, based on production environmentRolluppackaging
      • Quick cold start
      • Instant module hot update
      • True on-demand compilation
    • vue2.0I believe that many small partners are combinedwebpackDevelopment; But did you find that the initial project was cool when it was small and ran, compiled, and hot loaded quickly? Project one… Package, run, change a feature while hot loading… Let’s go to the toilet/get some water first. I hate this part when I’m busy
    • vue3.0In combination withviteThe author’s introduction is not affected by the huge size of the project, what started is what is now; It’s an exaggeration, of course, but not by much;

5. Environment construction

// For Vue 3, Vue CLI V4.5 should be available on NPM as @vue/cli@next yarn global add @vue/cli@next # OR NPM install -g@vue /cli@next // create project NPM Init viet-app <project-name> # OR yarn create viet-app <project-name> CD <project-name> NPM install NPM run dev // The project can be run and accessedCopy the code

Expansion: The project introduces other plug-ins such as VUe-Router4.0, Vuex4.0, typescript, etc. Please refer to Vue3.0 environment construction

6. Grammar introduction

Read through the changes vue3 has made to VUe2 before getting started. For details, click on the official documentation for major changes

The Options API is used in VUe2. In VUe3, Composition API is called purely functional API

6.1, the setup

The vue3 component entry is setup(){} function, which is executed only once by default; The execution order is after beforeCreate and before created;

. // Use props and this setup (props, CTX) {// Parameters passed between props components; Example CTX.$emit() attrs: Object emit: ƒ () listeners: Object parent: VueComponent refs: Object root: VueCopy the code

6.2. Life cycle

I remember the earlier vue3 is to remove the beforeCreate and created two life cycles; But when I did it, I found that I could write it; Because vue2 and vue3 are currently compatible;

created () { console.log('created') } setup (props, OnMounted (() => {})} mounted () {CTX) {console.log('setup')} // mounted () {CTX) {console.log('setup')} // mounted () { Console. log('mounted')} setup created mountedCopy the code

It’s compatible but try not to write this; Look ahead; It is highly recommended to put them all in the Steup function

Reactive, REF, toRefs, isRef

Create reactive objects reactive, REF, and toRefs, which correspond to data 3 in VUe2

// Return a number of times; <template> <div> <p>{{state.count}}</p> </div> </template> import {reactive} from 'vue'... setup(props, ctx) { const state = reactive({ count: 0 }) return { state } }Copy the code
/ / write two < template > < div > < p > {{count}} < / p > < / div > < / template > import {reactive} from 'vue'... setup(props, ctx) { const state = reactive({ count: 0 }) return { count: state.count } }Copy the code
// <template> <div> <p>{{count}}</p> </div> </template> import {reactive, toRefs} from 'vue' ... setup(props, ctx) { const state = reactive({ count: 0 }) return { ... toRefs(state) } }Copy the code
// Wrapped by ref(), the return value is an object, <template> <div> <p>{{count}}</p> <p>{{count}}</p> <p>{{count1}}</p> </div> </template> import {reactive, toRefs, ref} from 'vue' ... setup(props, // const count = ref(props. Count) console.log(count.value) // const count = ref(props state = reactive({ count1: ref(props.count) }) return { count, ... toRefs(state) } }Copy the code
Import {ref, isRef} from 'vue'; import {ref, isRef} from 'vue'; export default { setup(props, ctx) { const refCount = ref(0) const count = isRef(refCount) ? refCount : 1 } };Copy the code

6.4, the computed

Example scenario: Assign count to vue-router based on the current route strength, and extend the use of vue-router

<template> <div> <p>{{count}}</p> <p>{{count1}}</p> </div> </template> import {reactive, toRefs, computed} from 'vue' import {useRoute} from 'vue-router' ... Setup (props, CTX) {const route = useRoute() const state = reactive({// Count1 (() => {return route.path})}) const count1 = (() => {return route.path}) return {... ToRefs (state), // We don't need toRefs to calculate the property, because it is a concrete value.Copy the code

6.5. Watch and watchEffect

Example scenario: Same with computed

How watchEffect differs from Watch:

  1. watchEffectInstead of specifying the properties to listen to, dependencies are automatically collected. Whenever a callback references a reactive property, the callback is executed whenever the property changes
  2. watchOnly specified properties can be listened on
  3. watchYou can get new values and old values, andwatchEffectno
  4. watchEffectIt is executed once at component initialization to collect dependencies (andcomputedAgain, the callback is executed only if the dependencies collected later change
<template> <div> <p>{{count}}</p> </div> </template> import {reactive, toRefs, watch} from 'vue' import {useRoute} from 'vue-router' ... setup(props, ctx) { const route = useRoute() const state = reactive({ count: Watch (() => route.path, (newValue) => {state.count = newValue}, {immediate: true }) return { ... toRefs(state), } }Copy the code
<div> <p>{{count}}</p> </div> </template> import {reactive, toRefs, ref, watch} from 'vue' ... Setup (props, CTX) {// define data source let count = ref(0); Watch (count, (count, prevCount) => {console.log(count, prevCount) prevCount) }) setInterval(() => { count.value += 2 }, 2000) console.log(count.value) return { count } }Copy the code
<template> <div> <p>{{count}}</p> </div> </template> import {reactive, toRefs, watch} from 'vue'... setup(props, ctx) { const state = reactive({ name: 'vue', age: Age [() => state.name, () => state.age], () => state.age] oldAge]) => { console.log(oldname, oldname) console.log(oldAge, oldAge) }, { lazy: SetTimeout (() => {state.name = 'react' state.age += 1}, 3000) return {... toRefs(state), } }Copy the code
<template> <div> <p>{{count}}</p> </div> </template> import {reactive, toRefs, ref, watchEffect} from 'vue' import {useRoute} from 'vue-router' ... setup(props, ctx) { const route = useRoute() const state = reactive({ count: 0,}) // Print when route.path changes, WatchEffect (() => {count = route.path console.log(route.path)}) Const stop = watchEffect(() => {count = route.path console.log(route.path)}) Stop watchEffect listening if (...) { stop() } return { ... toRefs(state), } }Copy the code

Some of the apis and methods removed from Vue3

7.1 cancel KeyboardEvent keyCode

In ve2. X, the following code is used to bind keyboard events:

<! -- keyCode version --> <input v-on:keyup.13="submit" /> <! -- alias version --> <input v-on:keyup.enter="submit" />Copy the code

Or:

Vue.config.keyCodes = { f1: 112 } <! -- keyCode version --> <input v-on:keyup.112="showHelpText" /> <! -- custom alias version --> <input v-on:keyup.f1="showHelpText" />Copy the code

The keyCode(number) that assigns a button to keyUp in the event will not work in Vue3, but aliases can still be used, for example:

<input v-on:keyup.delete="confirmDelete" />
Copy the code

7.2 remove
o n . on,
Off and $once methods

In Ve2. X, component communication can be achieved via EventBus:

var EventBus = new Vue()
Vue.prototype.$EventBus = EventBus
...
this.$EventBus.$on()  this.$EventBus.$emit()
Copy the code

$on,$off, etc. (refer to RFC) are removed in Vue3 and mitt scheme is recommended instead:

import mitt from 'mitt'
const emitter = mitt()
// listen to an event
emitter.on('foo', e => console.log('foo', e) )
// fire an event
emitter.emit('foo', { a: 'b' })
Copy the code

7.3 remove filters

In Vue3, the filters item of the component can be removed and replaced with methods or computed:

<template>
  <p>{{ accountBalance | currencyUSD }}</p>
</template>
<script>
  export default {
    filters: {
      currencyUSD(value) {
        return '$' + value
      }
    }
  }
</script>
Copy the code

Replace with:

<template>
  <p>{{ accountInUSD }}</p>
</template>
<script>
  export default {
    props: {
      accountBalance: {
        type: Number,
        required: true
      }
    },
    computed: {
      accountInUSD() {
        return '$' + this.accountBalance
      }
    }
  }
</script>
Copy the code

Vue3 changes in API and writing

8.1 Instance Initialization

Initialize with new Vue() in ve2. X:

import App from './App.vue'
new Vue({
  store,
  render: h => h(App)
}).$mount('#app')
Copy the code

Vue is no longer a constructor in VUe3 and is initialized with the createApp method:

import App from './App.vue'
createApp(App).use(store).mount('#app')
Copy the code

8.2 Global API call method changed

In Vue2. X, most of the global APIS are called via vue. XXX or vue.abc (), for example:

  import Vue from 'vue'
  Vue.mixin()
  Vue.use()
Copy the code

In Vue3, these methods will be changed and replaced with the following:

  import { createApp } from 'vue'
  const app = createApp({})
  app.mixin()
  app.use()
Copy the code

At the same time, it is possible to import only the apis that are needed, and not the apis that are not. For example:

  import { nextTick,reactive,onMounted } from 'vue'
  nextTick(() => {
  })
  onMounted(() => {
  })
Copy the code

The Vue3 global API will be called by the methods of app.xxx, so the global methods and variables bound by vue.prototype. XXX will not be used.

/ / in the main. In js: app. Config. GlobalProperties. HTTP = function () {} / / in vue components: HTTP () this.Copy the code

8.3 Render method modification

In ve2. X, the render method is sometimes customized to return template content, as follows:

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

In Vue3, h is introduced through vue as follows:

import { h } from 'vue'
export default {
  render() {
    return h('div')
  }
}
Copy the code

8.4 New Method for Creating Asynchronous Components

In Ve2. X, especially in Vue Router, asynchronous components are often used. With the help of Webpack, the code of a component can be retrieved asynchronously, for example:

const asyncPage = () => import('./NextPage.vue')
const asyncPage = {
  component: () => import('./NextPage.vue'),
  delay: 200,
  timeout: 3000,
  error: ErrorComponent,
  loading: LoadingComponent
}
Copy the code

In Vue3, the defineAsyncComponent() method is provided to create asynchronous components and you can return a Promise object to control when the load completes, as follows:

import { defineAsyncComponent } from 'vue' const asyncPageWithOptions = defineAsyncComponent({ loader: () => import('./NextPage.vue'), delay: 200, timeout: 3000, error: ErrorComponent, loading: LoadingComponent }) const asyncComponent = defineAsyncComponent( () => new Promise((resolve, reject) => { /* ... * /}))Copy the code

Ix. Temporary Ending:

  1. Writing for a long time, writing a little wordy, the new API basically wrote several coding methods, according to their own preferences
  2. Gradually add some new API knowledge and usage
  3. Some references to this article are as follows:
  • Front End Morning Reading class article: the most complete guide to Vue3.0 upgrade
  • Vue Chinese Community article: an article about the new API in Vue3