Returns a REF object that explicitly controls dependency tracing and triggers responses

<template>
  <div>
    <div>{{ state }}</div>
    <button @click="handelClick">button</button>
  </div>
</template>

<script>
import { ref, customRef } from "vue";
// value: receives a parameter
function myRef(value) {
  // Returns a callback function that takes two arguments, namely, chasing changes and triggering updates
  return customRef((track, trigger) = > {
    return {
      get() {
        track(); // Tell Vue that the data needs to be tracked
        console.log("get", value);
        return value;
      },
      // A new value is received when updated
      set(newValue) {
        value = newValue; / / update the value
        console.log("set", newValue);
        trigger(); // Tell Vue to trigger interface update}}; }); }export default {
  setup() {
    let state = myRef(1);
    function handelClick() {
      state.value = 2;
    }
    return{ state,handelClick }; }};</script>

Copy the code

The effect

Why customize ref?

In the development of data may be local, may be on a remote server, if it is on a remote server needs to send request again to get the data network, and network request is an asynchronous operation, asynchronous operation requires the operations in an asynchronous function, if business complex will appear a large number of nested callback function. In the past we could solve this problem with async and await, but setup could only accept synchronous operations, but customRef can solve this problem

//index.vue
<template>
  <div>
    <ul>
      <li v-for="(item, index) in state" :key="index">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
import { ref, customRef } from "vue";
// value: receives a parameter
function myRef(value) {
  // Returns a callback function that takes two arguments, namely, chasing changes and triggering updates
  return customRef((track, trigger) = > {
    // Pass in the path, return promise
    fetch(value)
      .then((res) = > {
        return res.json(); // Convert to JSON for easy processing
      })
      .then((data) = > {
        // Retrieve the data returned by the server
        console.log(data);
        value = data;
        trigger(); // Tell Vue to trigger interface update
      })
      .catch((err) = > {
        // Print on failure
        console.log(err);
      });
    return {
      get() {
        track(); // Tell Vue that the data needs to be tracked
        console.log("get", value);
        // Note: no longer can get send network request, will be an infinite loop
        // Render page > call GET > Send network request
        // Save data > Update interface > call GET
        return value;
      },
      // A new value is received when updated
      set(newValue) {
        value = newValue; / / update the value
        console.log("set", newValue);
        trigger(); // Tell Vue to trigger interface update}}; }); }export default {
  setup() {
    // Resolve asynchrony
    let state = myRef("./data.json");
    // let state=ref([])
    // // passes in the path, returning a promise
    // fetch('./data.json')
    // .then((res)=>{
    // return res.json()// Convert to JSON for easy processing
    // })
    // .then((data)=>{
    // // Retrieve the data returned by the server
    // console.log(data);
    // state.value=data
    // })
    // .catch((err)=>{
    // // print when failure occurs
    // console.log(err);
    // })
    return{ state }; }};</script>

Copy the code
//data.json, need to remove this comment[{"id":1."name":"Huang zhong"},
    {"id":2."name":"Zhou yu"},
    {"id":3."name":Angela}]Copy the code

The effect

An asynchronous write

<template>
  <div>
    <ul>
      <li v-for="(item, index) in state" :key="index">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
import { ref, customRef } from "vue";
// value: receives a parameter
function myRef(value) {
  // Returns a callback function that takes two arguments, namely, chasing changes and triggering updates
  return customRef((track, trigger) = > {
    // Pass in the path, return promise
    fetch(value)
      .then((res) = > {
        return res.json(); // Convert to JSON for easy processing
      })
      .then((data) = > {
        // Retrieve the data returned by the server
        console.log(data);
        value = data;
        trigger(); // Tell Vue to trigger interface update
      })
      .catch((err) = > {
        // Print on failure
        console.log(err);
      });
    return {
      get() {
        track(); // Tell Vue that the data needs to be tracked
        console.log("get", value);
        // Note: no longer can get send network request, will be an infinite loop
        // Render page > call GET > Send network request
        // Save data > Update interface > call GET
        return value;
      },
      // A new value is received when updated
      set(newValue) {
        value = newValue; / / update the value
        console.log("set", newValue);
        trigger(); // Tell Vue to trigger interface update}}; }); }export default {
  setup() {
    // Resolve asynchrony
    let state = myRef("./data.json");
    // let state=ref([])
    // // passes in the path, returning a promise
    // fetch('./data.json')
    // .then((res)=>{
    // return res.json()// Convert to JSON for easy processing
    // })
    // .then((data)=>{
    // // Retrieve the data returned by the server
    // console.log(data);
    // state.value=data
    // })
    // .catch((err)=>{
    // // print when failure occurs
    // console.log(err);
    // })
    return{ state }; }};</script>

Copy the code