New changes for VUe3.0

I. Proxy (Core Principles)

  • motivation

  1. Because of ES5 Object.defineProperty, Vue cannot detect special changes to arrays and objects.
Vue 2.x // For Object const vm = new vue ({data:{a:1}}) // Vm. a is responsive vm.b = 2 // New attributes are non-responsive // For Array const vm = new Vue({ data: { items: ['a', 'b', 'c']}}) vm.items[1] = 'x' // not responsive (changing a normal value by indexing) vm.items. Length = 2 // Not responsive (changing length) Vue3.x does not have these limitations. Proxy is a proxy interception for the entire object level, rather than a hijacking for the attribute level by defineProperty.Copy the code

Proxy implements reactive Demo

function reactive(target){ if(! IsObject (target) {return target} const handlers = {// Attribute reading triggers the get() method get(target,key,receiver){const res = Reflect.get(target,key,receiver) return res }, / / property is set to trigger the set () method of the set (target, key and the value, the receiver) {the trigger (target, key) const res = Reflect. Set (target, key and the value, the receiver) return res }, // deleteProperty() method deleteProperty(target,key){const res = reflect.deleteProperty (target,key) return res}, } const observerd = new Proxy(target,handlers) return observerd} Age :26} let obj_= reactive(obj) // obj_. Name = 'zyd1' // obj_. Style = '1 Array(5).fill().map((item,i)=>i) let arr_ = reactive(arr) // arr_.push(5) arr_[1] = 100 arr_[100] = 100 // arr_.length =  0Copy the code
  1. Proxy has a new standard performance bonus that is better than defineProperty.
  • defects

    Does not support ie11Compatibility test

Composition-api (Core API)

Composition Api (Vue wants to combine functions to achieve logical splitting and reuse)

  • motivation

  1. Crosscutting points concern problemsOptions and Class Api code organization is not aggregated enough to organize code according to functions, resulting in scattered codes in Data, life cycle, Watch and computed.
  2. Logical splitting and reuseThe main way of vue2. X code reuse is to extract reusable components; Pure calculation method, can be extracted as a public method; But some common logic that doesn’t require a template (and is tied to states, events, life cycles, etc.) is hard to extract, and previous mixins, higher-order components, etc., have their drawbacks.

Vue3.x’s new composition-API solves these problems perfectly, similar to React-Hook, by combining functions responsible for a single function.

  • usage

    setup

    • Setup is a new component option that acts as an entry point for using the Composition API within the component.

        // book.vue
        export default {
            props: {
              title: String
            },
            setup(props,context:{attrs, slots, emit}) {
              console.log(props.title)
            }
        }
      Copy the code
    • Call time

      Before beforeCreate is called globally only once.

    • use

      <template> <div>{{ count }} {{ object.foo }}</div> </template> <script> import { ref, reactive } from 'vue' export default { setup() { const count = ref(0) const object = reactive({ foo: Return {count, object}}} </script>Copy the code
    • In the setup function, this is not the expected component instance; it is undefined, so do not access this under setup, even though this makes no sense.

    reactive

    Purpose: To achieve responsive detection of object data types

    Usage: Pass in a normal object and return a vUE propped reactive object

    Const Counter = {setup(){reactive Const state = reactive({count:0}) const add =()=>{state.count ++} Log (state) return {state, add}}, template: '<h1>{{state.count}}</h1><button @click="add">+</button>', };Copy the code

    ref

    Function: Used to detect basic data type values (such as String and Number) in a responsive manner

    Usage: Pass in a value that returns a vue internally wrapped {value: XXX} object, and change the value attribute to trigger a reactive update, which is used for template rendering without. Value being accessed in this way,vue internally unpacks automatically.

    Why is it designed this way?

    Because in JavaScript, primitive types (such as Number or String) are passed by value, not by reference.

    // Let a = {value:1} let b = a// let a = {value:1} //ref is a tool you implement inside VUE to turn a normal value into a wrapper object. Let a = ref(1) console.log(a) //{value:1} values are converted to objectsCopy the code
    Const Counter = {setup(){//ref Const count = ref(0) const add =()=>{count.value ++} console.log(count) return {count, add}}, template:`<h1>{{count}}</h1><button @click="add">+</button>`, };Copy the code

    Ref Common.value problem How serious is the problem? : Front-end guys are fighting over Vue3’s Ref-sugar proposal! When is the value needed? (1) If the value is used in your own code, it is needed. (2) Watch and other Vue apis are not needed (VUE automatically unpack them for you). (3) Template value is not needed. XxxRef can be avoided to some extent, or use ref: syntactic sugar.

    ToRef, toRefs

    Role: A reference to a proxy object returned by Reactive must be kept during the passing of a composite function to ensure that the object is responsive and cannot be deconstructed or disassembled by ES6 properties. ToRef method

    Const pos = reactive({x:0, y:0}) const xRef = toRef(pos,'x') const yRef = toRef(pos,'y')Copy the code

    ToRefs method

    Const pos = reactive({x:0, y:0}) const pos = reactive({x:0, y:0}) Const posRefsObj = useRefs(pos) {x:toRef(pos,'x') y:toRef(pos,'y')}Copy the code

    computed

    Function: In accordance with vue2. X, a new value is calculated according to the change of the dependent value in the function. Usage: Pass in a function that returns a wrapped {value: XXX} responsive reference object.

    Const Counter = {setup(){const state = reactive({count:0}); Font switch red-green color let isOdd = computed(()=>state.count%2 === 0) const add =()=>{state.count ++} return {state, isOdd, add } }, template:`<h1 :style="{'color':isOdd? 'red':'green'}">{{state.count}}</h1><button @click="add">+</button>`, };Copy the code

    watch

    Role: Same as vue2. X, active monitoring of responsive data, data changes, user incoming callback.

    Const state = reactive({count:0}) const state = reactive({count:0}) Font switch red-green color let isOdd = computed(()=>state.count%2 === 0) watch(isOdd,(newValue)=>{alert(newValue? }) const add =()=>{state.count ++} return {state, isOdd, add}}, template: '<h1 :style="{'color':isOdd? 'red':'green'}">{{state.count}}</h1><button @click="add">+</button>`, };Copy the code

    The life cycle

    Option to API compositonAPI
    beforeCreate No need *
    created No need *
    beforeMount onBeforeMount
    mounted onMounted
    beforeUpdate onBeforeUpdate
    updated onUpdated
    beforeUnmount onBeforeUnmount
    unmounted onUnmounted

Compared with the react – hook

  1. Different mental burdens

The problem with react-hook is that it is always worried about triggering updates frequently. UseEffect is the last escape pod that controls code from being executed frequently. However, if the dependency array is set incorrectly, it will cause side effects such as incorrect execution timing and the bug of fetching old closure values. UseCallBack is often used to avoid triggering unnecessary child component rendering. The vue-CompositonAPI has the opposite problem of constantly worrying about triggering updates, such as reactive loss due to deconstruction, which vue fixes by introducing refs but creates a new problem of always forgetting to write.value. 2. Different views on life cycle. React-hook deliberately weakens the concept of life cycle and instead advocates the concept of rendering side effects, which are caused by data changes. Or another point of view is that react uses useEffect to achieve aggregation and encapsulation of life cycle.

/ / hook useEffect (() = > {alert (' components mounted) return () = > {/ / component uninstall to remove side effects alert (' component uninstall ')}}, []); / / compositonApi onMounted (() = > {alert (' mount components')}) onUnmounted (() = > {alert (' component uninstall ')})Copy the code

Vue-compositonapi is still familiar with the VUe2. X lifecycle and does not add new understanding costs

CompositionAPI practice Demo (and compared with hook) common top loading and pull-up Demo.

Other changes

  • Teleport
  • Components are no longer limited to a single root element
  • Data option, all in function form (previously the root component is an object, child component is a function)
  • $children is deprecated and can only be retrieved from the ref component and DOM.
  • And so on. Please refer to the official documentation for more information