Compostition API collection to solve Vue2 component development problems

Better TypeScript support

New Api support

What is Reactive?

  • Reactive is the method provided in VUE3 for implementing reactive data
  • Reactive data is implemented via defineProperty in VUe2
    • Due to a flaw in dealing with arrays, reactive data in VUe3 is implemented using ES6 proxies

Reactive attention

  • Reactive parameters must be objects (JSON/ARR)
  • If you pass other objects to Reactive
    • By default, the interface is not automatically updated when objects are modified.
    • If you want to update, you can do it by reassigning.

What is the ref?

  • Ref, like Reactive, is used to implement reactive data
  • Because Reactive must pass an object, it can be a hassle in enterprise development if we only want a variable to be reactive, so VUe3 provides us with the ref method to listen on the simple

Ref nature

  • The underlying nature of a REF is reactive, and the system will automatically convert it to something like this based on the value we pass in to the REF

    ref(xxx) => reactive({value:xxx})
    Copy the code

Ref attention

  • Variables declared using ref in vue do not need to be retrieved by.value in the template because vue automatically adds.value to us in the Template
  • Using or changing the value of ref in JS must be obtained and changed via.value

Recursive listening

  • By default, both ref and Reactive are recursive listening

  • The problem with recursive listening is that if the data volume is large, it can be very performance consuming

  • Non-recursive listening

shallowReactive

    let state = shallowReactive({
      a: "a".b: {
        c: "c".d: {
          e: "e"}}})Copy the code

Note: shallowReactive is used to create non-recursive listening properties that only listen on the first layer

shallowRef

    let state = shallowRef({
      a: "a".b: {
        c: "c".d: {
          e: "e"}}})Copy the code

Note: shallowRef listens for. Value changes. This is not a change to the first layer of shallowReactive.

triggerRef

    let state = shallowRef({
      a: "a".b: {
        c: "c".d: {
          e: "e"}}})// The page does not update the view after modification
    state.b.d.e = "ee"
    // Actively triggers view updates
    triggerRef(state)
Copy the code
  • Application scenarios

    Half the cases we use the ref and reactive can, only if the need to monitor the amount of data is large, we only use shallowRef/shallowReactive

toRaw

Before we get to toRaw, we can take a look at the following example to understand why toRaw is needed

<script lang="ts">
import { reactive } from "vue";

export default {
  name: "App".setup() {
    let data = {
      name: "Just tomato and eggs.".age: 18};let state = reactive(data);
    
    function changeAge() {
      // state.age += 1;
      data.age += 1;
      console.log(data);
      console.log(state);
    }
    return{ state, changeAge, }; }}; </script>Copy the code

We’ll see that the data has changed but the view hasn’t been updated. One thing we understand here is that data and state are references. The essence of state is a Proxy object in which data is referenced

If you modify data directly, the data is changed, but you cannot trigger an update to the page

Page updates are triggered only if they are modified by the wrapped object

Where this method is useful is when we just want to modify the data, but don’t want the view to change. Because the nature of the REF and Reactive data types is that every change to the data is tracked and the UI is updated. Very performance consuming. If we have an operation that does not need to track and update the page, then we can use toRaw method to get its raw data. This saves performance

Summary: The toRaw method retrieves raw data from reactive data

Note: When we get raw data of type REF through toRaw, we will find that we cannot get it.

Reactive

Ref(obj) => reactive({value: obj})

So that’s why you need dot value to get the data that ref created, right

Summary: If you want to retrieve the raw data of type ref from toRaw, you must explicitly tell the toRaw method the value of.value to retrieve. After Vue processing,.value saves the original data.

<script lang="ts">
import { ref, toRaw } from "vue";

export default {
  name: "App".setup() {
    let data = {
      name: "Just tomato and eggs.".age: 18};let state = ref(data);
    let data2 = toRaw(state.value);
    console.log(data2);

    function changeAge() {
      // state.age += 1;
      data.age += 1;
      console.log(data);
      console.log(state);
    }
    return{ state, changeAge, }; }}; </script>Copy the code

Markrow

Data that is never traced, variables declared by Markrow are never traced, even if they are declared by reactive or REF. Modifying the data does not change the data, nor does it trigger a view update

Ref and toRef

  • Both ref and toRef modify responsive data to affect previous data
  • The interface updates automatically when the REF data changes
  • The toRef data changes and the interface does not automatically update

ToRef application scenario: This can be used if you want to associate reactive data with previous data and do not want to update the UI after updating reactive data.

toRefs

Converts a reactive object to a normal object, where each property of the resulting object is a REF pointing to the corresponding property of the original object.

Or to make all properties of an object responsive data available. All of these methods are designed to improve performance. Ref and Reactive are the main ones used

customRef

Create a custom REF with explicit control over its dependency trace and update trigger. It requires a factory function that takes track and trigger functions as arguments and should return an object with get and set.

Why we need to customize ref is discussed below. How do you do that

<script lang="ts">
import { customRef } from "vue";

function myRef(value) {
  return customRef((track, trigger) = > {
    return {
      get() {
        The track() method tells vue that the data is to be tracked
        track();
        console.log("get", value);
        return value;
      },
      set(newValue) {
        value = newValue;
        console.log("set", value);
        The trigger() method tells vue to update the viewtrigger(); }}; }); }export default {
  name: "App".setup() {
    let state = myRef(18);
    function change() {
      state.value = 20;
    }
    return{ state, change, }; }}; </script>Copy the code

Why customize ref

The first thing we need to know is that the setup function can only be a synchronous function, not an asynchronous function. Async: async: async: async: async: async: async: async: async: async

So when we need to make ajax requests to get data in business, and want to get data with async await is not possible.

Not being able to use async await means a lot of callback functions in our code.

If we still want to write the same way we wrote the synchronized code before, we can consider using a custom ref.

<script lang="ts">
import { customRef } from "vue";

function myRef(value) {
  return customRef((track, trigger) = > {
    fetch(value)
      .then(async (res) => {
        value = await res.json();
        console.log(value);
        trigger();
      })
      .catch((reason) = > {
        console.log(reason);
      });

    return {
      get() {
        The track() method tells vue that the data is to be tracked
        track();
        console.log("get", value);
        return value;
      },
      set(newValue) {
        value = newValue;
        console.log("set", value);
        The trigger() method tells vue to update the viewtrigger(); }}; }); }export default {
  name: "App".setup() {
    let state = myRef(".. /public/data.json");
    function change() {
      state.value = 20;
    }
    return{ state, change, }; }}; </script>Copy the code

Ref fetch element

Unlike VUe2, vue3 doesn’t have the this.$attribute anymore. It’s also easy to get elements

<template>
  <div>
    <div ref="box">I am a box</div>
  </div>
</template>

<script lang="ts">
import { onMounted, ref } from "vue";

export default {
  name: "App".setup() {
    let box = ref(null);
    onMounted(() = > {
      console.log(box.value);
    });
    return{ box, }; }};</script>
Copy the code

Note here why box-value is printed for the same reason ref declared the variable fetch above.

Why print in onMounted? This is the same life cycle as 2. Because setup and Created are the same as beforeC reated, the DOM is not created during this period

Readonly family

  • readonly

A read-only proxy that accepts an object (reactive or pure) or ref and returns the original object. A read-only proxy is deep: any nested property accessed is also read-only.

Use to create a read-only property that is recursively read-only

  • shallowReadonly

Used to create a read-only data, but not recursively read-only. Only the first layer is read-only

  • isReadonly

Returns a Boolean value to determine if the property is a readonly

Now, you might be a little bit confused here so I’m just going to declare a variable that’s const. Be careful here. Const is usually used to declare constants and is usually a primitive type. But if you declare a reference type. Random variables cannot be reassigned. However, the value of an attribute of a reference type can be changed.

Understanding the nature of responsive data

  • In ve2. X, reactive data is implemented via defineProperty. However, there are some defects, such as array handling

  • In Vue3. X, reactive data is implemented by Proxy

// Simple implementation
let obj = { name: "Tomato".age: 18 }
let state = new Proxy(obj, {
    get(obj, key) {
        console.log(obj, key); // {name: 'tomato ', age: 18} name
    },
    set(obj, key, value) {
        console.log(obj, key, value); // {name: 'tomato ', age: 18} name
        obj[key] = value
        console.log("Update UI view");
      	return true}})console.log(state.name); / / tomato
state.name = "Fried egg"
console.log(state); // Proxy {name: ' ', age: 18}
Copy the code

By the simple example above. We can do a lot of things in getting values and setting values.

Note: the set method must return a value indicating that the operation completed successfully. Because it’s possible to make more than one change in a set operation like an array

Proxy Array

// Simple implementation
let arr = [1.2.3]
let state = new Proxy(arr, {
    get(obj, key) {
        console.log(obj, key); // [1, 2, 3] 1
        return obj[key]
    },
    set(obj, key, value) {
        /** * [1, 2, 3] push [1, 2, 3] length [1, 2, 3] 3 4 Update UI view [1, 2, 3, 4] */
        console.log(obj, key, value);
        obj[key] = value
        console.log("Update UI view");
        return true}})// console.log(state[1]) // 2
state.push(4)
console.log(state);
Copy the code

Using the above code we can see that the set method is executed twice. One is [1, 2, 3] 3, 4, and one is [1, 2, 3, 4] length 4

The set method must tell whether the current operation was successful by returning a value. An error is reported if the above return ture is overlooked

state.push(4)
      ^

TypeError: 'set' on proxy: trap returned falsish for property '3'
    at Proxy.push (<anonymous>)
    at Object.<anonymous> (/Users/cctvabu/vite-vue3-project/proxy.js:26:7)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions.. js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47
Copy the code

Note that the set method must tell you whether the current operation was successful by returning a value


So that’s part of what I learned about API. The follow-up is still in the study and supplement. Of course there are incorrect places please comment pointed out, I refer to the information for modification.

Looking for a job

I am planning to job-hopping recently. Have the introduction work can contact me ha ~