Vue3.0 learning notes

Posted by happyhappy on Fri, 14 Jan 2022 03:54:21 +0100

catalogue

         1, Composite API

2, reactive function

3, ref function

4, Difference between ref and reactive:

5, Recursive listening and non recursive listening

Recursive listening

Non recursive listening

Application scenario

6, toRaw

7, markRaw

8, ref, toRef, toRefs

1, Composite API

The setup function is the entry function of the composite API.

The setup function is executed before beforeCreate.

data and methods cannot be used in the setup function. To avoid errors, this in setup is undefined.

The setup function is synchronized.

Note:
1. The variables / methods defined in the composition API must be exposed through {XXX, XXX} if they want to be used outside.
2. In the composition API, the defined methods do not need to be defined in methods, but can be defined directly.

2, reactive function

1. What is reactive?

reactive is the method of implementing responsive data provided in vue3. The responsive data in vue2 is implemented using defineProperty. Implementing responsive data in vue3 uses the proxy method in ES6.

Note:

  1. The parameter of reactive must be in the form of an object (json/arr).
  2. If other objects are passed to reactive, the object will be modified by default, and the interface will not be updated. If you want to update, you can assign values.        
<template>
  <div>
    <p>{{ user }}</p>
    <button @click="increase">click me! one year later</button>
  </div>
</template>
 
<script>
import { reactive } from "vue";
export default {
  name: "reactive",
//Create a responsive data
//Essence: it is to wrap the incoming data into a proxy object
  setup() {
    const user = reactive({ name: "Alice", age: 12 });
    function increase() {
      ++user.age
    }
    return { user, increase };
  },
};
</script>

III. ref function

1. What is ref function?

Ref, like reactive, is also used to implement responsive data. Because you need to pass an object in the reactive function, it will be very troublesome to implement a single object in enterprise development. Therefore, vue3 provides a ref method to monitor simple values.

2. Essence of ref

The underlying essence of ref is actually reactive. The system will convert it into reactive according to the value of ref we pass in

ref(xxx)------->> reactive({ value:xxx })

3. Precautions for ref:

The value of ref used in vue is not obtained through value.  

The value of ref in js must be obtained through value.  

4, Difference between ref and reactive:

If the ref type is data in the template, vue will automatically add it for us value

If the template uses reactive data, vue will not automatically add it for us value

How does vue decide whether to automatically add ref type?

vue will automatically determine the ref type before parsing the data. If yes, it will be added value, otherwise No.

How does vue determine whether the current data is ref type?

Through the _ofthe current data_ v_ref. if there is this private attribute and the value is true, it represents a ref type data.

We can also judge the current data type by the true and false values of isRef and isReactive.

5, Recursive listening and non recursive listening

Recursive listening

By default, both ref and reactive listen recursively, that is, data changes can be monitored in real time.

Note: recursive listening has a big problem. If the amount of data is large, it will consume performance.

In reactive:

<template>
<div>
  <p>msg.a.b.c = {{msg.a.b.c}}</p>
  <p>msg.e.f = {{msg.e.f}}</p>
  <p>msg.g = {{msg.g}}</p>
  <button @click="c">button</button>
</div>
</template>

<script>
import { reactive } from 'vue'
export default {
  name: 'App',
  setup() {
    let msg = reactive({
      a: {
        b: {
          c: 'c'
        }
      },
      e: {
        f: 'f'
      },
      g: 'g'
    });
    function c() {
      console.log(msg);
      msg.a.b.c = 'C';
      msg.e.f = 'F';
      msg.g = 'G';
    };
    return {
      msg,
      c
    };
  }
}
</script>

In ref:

<template>
<div>
  <p>msg.a.b.c = {{msg.a.b.c}}</p>
  <p>msg.e.f = {{msg.e.f}}</p>
  <p>msg.g = {{msg.g}}</p>
  <button @click="c">button</button>
</div>
</template>

<script>
import { reactive } from 'vue'
export default {
  name: 'App',
  setup() {
    let msg = ref({
      a: {
        b: {
          c: 'c'
        }
      },
      e: {
        f: 'f'
      },
      g: 'g'
    });
    function c() {
      console.log(msg);
      msg.value.a.b.c = 'C';
      msg.value.e.f = 'F';
      msg.value.g = 'G';
    };
    return {
      msg,
      c
    };
  }
}
</script>

Non recursive listening

shallowRef / shallowReactive

If you create data through shallowRef, you are listening for The change of value, not the change of the first layer. ß

How to trigger non recursive listening to update the page?

If it is data of type shallowRef, trigger it through triggerRef.

In "shallowReactive", there is no "trigger" scheme to actively wake up and monitor changes.

(1) The essence of shallowRef: the data created through shallowRef listens to value changes, because the bottom layer is essentially the first layer.

<template>
    <div></div>
</template>
<script setup>
    import { reactive } from 'vue'
    import { shallowReactive } from 'vue'
    import { shallowRef } from 'vue'
    export default {
        setup() {
            //  ref  ->  reactive
            // ref(10) -> reactive({value:10})
            // shallowRef -> shallowReactive
            // shallowRef(10) ->  shallowReactive({value:10}) 
          let state1 = shallowRef({
                a: 'a',
                gf: {
                    b: 'b',
                    f: {
                        c: 'c',
                        s: {
                            d: 'd'
                        }
                    }
                }
            })

            let state2 = shallowReactive({
                value: {
                    a: 'a',
                    gf: {
                        b: 'b',
                        f: {
                            c: 'c',
                            s: {
                                d: 'd'
                            }
                        }
                    }
                }
            })

        }
    }
</script>

Application scenario

Generally, we can monitor data changes and use ref and reactive

If the amount of data is large, we use shallowReactive and shallowRef to monitor data changes.

6, toRaw

Features of ref/reactive data type: each modification will be tracked, and the ui interface will be updated, which is very performance consuming

If you do not need to update the ui interface and the data will not be tracked, you can use toRaw to get the original data and modify the original data. This improves performance.

Note: when the parameter received by the toRaw method is a ref object, you need to add value to get the original data object.

toRaw in reactive

<template>
  <div>
      <p>{{state}}</p>
    <button @click="myFn">Button</button>
  </div>
</template>

<script>
  /*
  1.toRaw
  Get raw data from Reactive or Ref

  2.toRaw effect
  Do something you don't want to be monitored (improve performance)
  * */
  import {reactive, toRaw} from 'vue';
export default {
  name: 'App',
  setup() {
    
      /*
      ref/reactive Characteristics of data type:
      Each modification will be tracked and the UI interface will be updated, but this is actually very performance consuming
      So if we don't need to track some operations and update the UI interface, at this time,
      We can get its original data through toRaw method and modify the original data
      In this way, it will not be tracked, and the UI interface will not be updated, so the performance is good
      * */
      let state = reactive(
        {name:'lnj', age:18}
      );
      // Get source data of state
      let obj2 = toRaw(state);
      // console.log({name:'lnj', age:18} === obj2); // true

      // console.log({name:'lnj', age:18} === state); // false

      function myFn() {
        // The obtained source data changes and does not trigger page update
          obj2.name = 'zs';
          console.log(obj2); // {name: "zs", age: 18}
          // state.name = 'zs';
          // console.log(state);// {name: "zs", age: 18}
      }
    return {state, myFn}
  }
}
</script>

<style>

</style>

toRaw in ref

<template>
  <div>
      <p>{{state}}</p>
    <button @click="myFn">Button</button>
  </div>
</template>

<script>
  import { toRaw, ref} from 'vue';
export default {
  name: 'App',
  setup() {
      /*
      1.ref Essence: reactive
      ref(obj) -> reactive({value: obj})
      * */
      let state = ref({name:'lnj', age:18});
      // Note: if you want to get the raw data of ref type (the data passed in during creation) through toRaw
      //        Then you must explicitly tell the toRaw method that what you want to get is Value of value
      //        Because after Vue processing value is the original data passed in when it was created
      // let obj2 = toRaw(state);
      let obj2 = toRaw(state.value);
      console.log(state);
      console.log(obj2);

      function myFn() {
        // The obtained source data changes and does not trigger page update
          obj2.name = 'zs';
          console.log(obj2); // {name: "zs", age: 18}
          // state.name = 'zs';
          // console.log(state);// {name: "zs", age: 18}
      }
    return {state, myFn}
  }
}
</script>

<style>

</style>

7, markRaw

Mark data as never traceable

<template>
  <div>
      <p>{{state}}</p>
    <button @click="myFn">Button</button>
  </div>
</template>

<script>
  /*
  1.markRaw
  Mark data as never traceable
  It is generally used when writing your own third-party library
  * */
  import {reactive, markRaw} from 'vue';
export default {
  name: 'App',
  setup() {
      let obj = {name: 'lnj', age: 18};
      // Can't track, listen, as responsive data
      obj = markRaw(obj);
      let state = reactive(obj);
      function myFn() {
        // The data has changed, but the page ui has not changed
          state.name = 'zs';
      }
    return {state, myFn}
  }
}
</script>

<style>

</style>

8, ref, toRef, toRefs

1. Difference between ref and toRef
(1). ref is essentially a copy, and modifying responsive data will not affect the original data; The essence of toRef is a reference relationship. Modifying responsive data will affect the original data
(2). If the ref data changes, the interface will be updated automatically; toRef when the data changes, the interface will not be updated automatically
(3). The transmission of toRef is different from the participation of ref; toRef receives two parameters. The first parameter is which object and the second parameter is which attribute of the object
 

2. Difference between toRef and toRefs:

(1) toRef is to create a ref data, which is associated with the original data

(2) toRefs is batch created ref data, which is associated with the original data

ref Code:

<template>
  <div>
      <p>{{state}}</p>
    <button @click="myFn">Button</button>
  </div>
</template>

<script>

  import {ref} from 'vue';
export default {
  name: 'App',
  setup() {
      let obj = {name:'lnj'};
 
      let state = ref(obj.name);
 

      function myFn() {
          state.value = 'zs';
          console.log(obj); //{name:'lnj'}
          console.log(state); // {name:'zs'}
      }
    return {state, myFn}
  }
}
</script>

<style>

</style>

toRef Code:

<template>
  <div>
      <p>{{state}}</p>
    <button @click="myFn">Button</button>
  </div>
</template>

<script>
  /*
  1.toRef
  Create a ref type data and associate it with the previous data
  2.toRefs
  Batch create ref type data and associate with previous data
  3.toRef Difference between and ref
  ref-The created data has nothing to do with the past (replication)
  toRef-The created data is related to the previous (Reference)
  ref-Data changes will automatically update the interface
  toRef-Data changes will not automatically update the interface
  * */
  import {ref, toRef} from 'vue';
export default {
  name: 'App',
  setup() {
      let obj = {name:'lnj'};
      /*
      ref(obj.name) -> ref(lnj)
      -> reactive({value:lnj})
      * */
      // Ref - > copy
      // let state = ref(obj.name);
      // Toref - > reference
      /*
      ref Difference between and toRef:
      ref->Copying and modifying responsive data will not affect the previous data
      toRef->Referencing and modifying responsive data will affect previous data
      ref->When the data changes, the interface will be updated automatically
      toRef->If the data changes, the interface will not be updated automatically

      toRef Application scenario:
      If you want to associate the responsive data with the previous data, and you don't want to update the UI after updating the responsive data, you can use toRef
      * */
      let state = toRef(obj, 'name'); 

      function myFn() {
          state.value = 'zs';
          /*
          Conclusion: if you use ref to turn the attributes in an object into responsive data
               When we modify the responsive data, it will not affect the obj of the original data== state
          * */
          /*
          Conclusion: if you use toRef to turn the attributes in an object into responsive data
               Modifying the responsive data will affect the original data
               However, if the responsive data is created through toRef, modifying the data will not trigger the update of the UI interface
          * */
          console.log(obj);  //{name:'zs'}
          console.log(state);  //{name:'zs'}
      }
    return {state, myFn}
  }
}
</script>

<style>

</style>

toRefs Code:

<template>
  <div>
      <p>{{state}}</p>
    <button @click="myFn">Button</button>
  </div>
</template>

<script>
  /*
  1.toRef
  Create a ref type data and associate it with the previous data
  2.toRefs
  Batch create ref type data and associate with previous data
  3.toRef Difference between and ref
  ref-The created data has nothing to do with the past (replication)
  toRef-The created data is related to the previous (Reference)
  ref-Data changes will automatically update the interface
  toRef-Data changes will not automatically update the interface
  * */
  import {ref, toRef, toRefs} from 'vue';
export default {
  name: 'App',
  setup() {
      let obj = {name:'lnj', age:18};
      // let name = toRef(obj, 'name');
      // let age = toRef(obj, 'age');
      let state = toRefs(obj);

      function myFn() {
          // name.value = 'zs';
          // age.value = 666;
          state.name.value = 'zs';
          state.age.value = 666;
          console.log(obj); //{name:'zs', age:666}
          console.log(state);  //{name:'zs', age:666}
          // console.log(name); 
          // console.log(age);
      }
    return {state, myFn}
  }
}
</script>

<style>

</style>

Topics: Front-end Vue.js