A few sweets from VUe3

1. suspense

A built-in component with slots

<suspense> <template #default> <main-model></main-model> </template> <template #fallback> <div>loading</div> </template>  </suspense>Copy the code

2.Fragment

In VUe2, a component can have only one root node, but Vue3 is no longer limited by this restriction and automatically stores multiple elements in a virtual element fragment

< the template > < h1 > primary title < / h1 > < h2 > secondary title < / h2 > < h2 > secondary title < / h2 > < h2 > secondary title < / h2 > < / template >Copy the code

3.teleport

Portal — Similar to the appendTo property of the Dialog component in ElementUI, it transfers the HTML structure of the component to the specified container element, typically used in the dialog case.

<template> <div @click="showDialog = true"> Open popup </div> <teleport to="body"> <div class="mask" V-show ="showDialog"> <div Class ="dialog"> <h3> < button@click ="showDialog = false">Copy the code

Second, the Composition API

If components are written according to the option configuration method of VUe2, the amount of code will increase as the service complexity becomes higher and higher. As the codes of related businesses need to be written to specific areas according to the configuration of Option, subsequent maintenance is very complicated and the code reusability is not high. Comcomposition API is born to solve this problem

Let’s start with a few basic apis:

1. setup

  • When an object is returned, the attribute methods in the object can be used directly in the template
  • Returns the render function, then you can customize the render content
Setup (){function sayHello(){alert(' I am ${name}, I am ${age} old, I am ${age} old, Function test2(){console.log(this.sex) console.log(this.saywelcom)} return {name, age, sayHello, Test2} / / return a function (rendering function) / / return () = > h (' h1 ', 'SSJ)}Copy the code

2. Ref: Define responsive data

  • The data received can be of either primitive or object type
  • Basic type: Responsivity is still done by object.defineProperty () get and set
  • Object type: Internal help to a new function in Vue3.0 ————reactive function
import {ref} from 'vue'

<script>
    setup(){
        let name = ref("suosuojiang") //
        function changeInfo(){
            name.value = "ssj"
        }
        return {
            name,
            changeInfo
        }
    }
</script>
Copy the code

3.reactive

  • The function is to define the responsive data of the object type (do not use it for basic types, use ref).
  • Return a proxy object proxy
  • Reactive definition of reactive data is deep

4. Watch and watchEffect

  • The configuration of Watch and VUE2 is basically the same, but there are some flaws:
  • When listening to reactive data defined by Reactive, the deep configuration is invalid and oldValue cannot be correctly obtained
  • The deep configuration is effective when monitoring a property in an object defined by Reactive
  • WatchEffect does not specify which object to listen on; it listens on whomever is used in the callback
Watch (sum, (newV, oldV)=>{console.log('sum changed ',newV, oldV)},{immediate: True}) // Watch ([sum, MSG], (newV, oldV)=>{console.log(' MSG value changed ',newV, oldV)}) Monitor all properties of reactive data defined by Reactive 1. Note: oldV cannot be obtained correctly here. */ watch(person,(newV, oldV)=>{console.log('person value changed ',newV, oldV)},{deep:false}) Watch (()=> person.age,(newV, oldV)=>{console.log('person's age changed ',newV, oldV)}) Watch ([()=> Person.name,()=> person.age],(newV, OldV)=>{console.log('person name and age changed ',newV, oldV)}) // Special case watch(()=> person.jobs,(newV, OldV)=>{console.log('person job changed ',newV, oldV)},{deep:true}) WatchEffect (()=>{const x1 = sum.value console.log(' watchEffect ')=>{const x1 = sum. ')})Copy the code

5.computed

Two ways to write it:

Person.fullname = computed(()=>{return person.firstName + '-' + person.lastname}) // Compute attributes - full write let fullName = computed({get(){return person.firstName + '-' + person.lastName}, set(value){ const nameArr = value.split('-') person.firstName = nameArr[0] person.lastName = nameArr[1] } })Copy the code

6. Life cycle

Three, performance optimization: fast and small

Vue3 is nearly 2 times faster than VUE2 in terms of performance and is 1/3 to 1/2 smaller when packaged.

1. Optimization of diFF algorithm:

The virtual DOM in VUe2 is a full comparison

< the template > < h1 > primary title < / h1 > < h2 > {{title}} < / h2 > < h2 > secondary title < / h2 > < h2 > secondary title < / h2 > < / template >Copy the code

In VUe3, PatchFlag is added. Only nodes with PatchFlag are compared, and the specific content of the node to be compared is determined by the information of the current PatchFlag.

Supplementary: Core idea of PatchFlag: Different patch methods will be executed according to the properties of vNode’s patchFlag. If there is no patchFlag, full diff will be executed, that is, patchProps, which should contain most of the following individual patches. That is:

  • patchClass
  • patchStyle
  • patchEvent
  • , etc.

For example:

<template>
  <div :class="classNames" :id="id">{{name}}</div>
</template>
Copy the code

The compiled:

createElement( "div", { class: classNames, id: Id}, [name], PatchFlags. TEXT | PatchFlags. CLASS | PatchFlags. PROPS, [" id "] / / name that a few specific PROPS is dynamic)Copy the code

2. Vue2 response formula depends on the principleObject.definePropertyThe hijacking of data; Vue3 byProxyIntercepts the changes of any property in the object, including the read and write of the property, add and delete, and also passReflectOperates on properties of the proxied object (source object)

3. tree-shaking

The core apis all support tree-shaking and are brought in through packages rather than being injected directly at instantiation, only the functionality or features used are packaged (packaged on demand) and therefore smaller.

Four, other

1. Customize hooks

import { onMounted, onUnmounted, ref } from "vue";

function useWindowResize() {
  const width = ref(0);
  const height = ref(0);

  function onResize() {
    width.value = window.innerWidth;
    height.value = window.innerHeight;
  }

  onMounted(() => {
    window.addEventListener("resize", onResize);
    onResize();
  });

  onUnmounted(() => {
    window.removeEventListener("resize", onResize);
  });

  return {
    width,
    height
  };
}

export default useWindowResize;
Copy the code
< the template > < div id = "app" > < h1 > {{count}} < / h1 > < button @ click = "plus" > plus < / button > < h1 > screen size: < / h1 > < div > width: {{width}}</div> <div> height: {{height}}</div> </template> <script lang="ts"> import {ref, watch} from "vue"; import useWindowResize from "./hooks/useWindowResize"; export default { name: "App", setup() { const count = ref(0); function plus() { count.value++; } watch(count, () => { document.title = "update: " + count.value; }); const { width, height } = useWindowResize(); return { count, plus, width, height }; }}; </script>Copy the code

2. Better TypeScript Support