1. 程式人生 > 其它 >customRef---建立一個自定義ref

customRef---建立一個自定義ref

技術標籤:前端vuejavascript前端vue.js

返回一個ref物件,可以顯式地控制依賴追蹤和觸發響應

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

<script>
import { ref, customRef } from "vue";
// value:接收一個引數
function myRef(value) { // 返回一個回撥函式,接收兩個引數,分別是追中變化與觸發更新 return customRef((track, trigger) => { return { get() { track(); //告訴Vue這個資料是需要追蹤變化的 console.log("get", value); return value; }, // 更新時會接收一個新值 set(newValue) { value = newValue;
//更新值 console.log("set", newValue); trigger(); //告訴Vue觸發介面更新 }, }; }); } export default { setup() { let state = myRef(1); function handelClick() { state.value = 2; } return { state,handelClick }; }, }; </script>

效果
在這裡插入圖片描述

為什麼要自定義ref?

在開發中獲取的資料有可能是本地的,也有可能是遠端伺服器上的,如果是遠端伺服器上的需要傳送網路請求再獲取資料,而網路請求是一個非同步操作,非同步操作則需要在非同步函式裡面操作,如果業務複雜的話就會出現大量回調函式巢狀的情況.

過去我們可以通過async和await解決,但在setup只能接受同步操作,但是customRef就可以解決這一問題

//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:接收一個引數
function myRef(value) {
  // 返回一個回撥函式,接收兩個引數,分別是追中變化與觸發更新
  return customRef((track, trigger) => {
    // 傳入路徑,返回promise
    fetch(value)
      .then((res) => {
        return res.json(); //為了方便處理轉換成json
      })
      .then((data) => {
        // 拿到伺服器返回的資料
        console.log(data);
        value = data;
        trigger(); //告訴Vue觸發介面更新
      })
      .catch((err) => {
        // 失敗的時候列印
        console.log(err);
      });
    return {
      get() {
        track(); //告訴Vue這個資料是需要追蹤變化的
        console.log("get", value);
        //注意:不能再get傳送網路請求,會死迴圈
        //渲染頁面>呼叫get>傳送網路請求
        //儲存資料>更新介面>呼叫get
        return value;
      },
      // 更新時會接收一個新值
      set(newValue) {
        value = newValue; //更新值
        console.log("set", newValue);
        trigger(); //告訴Vue觸發介面更新
      },
    };
  });
}
export default {
  setup() {
    // 解決非同步
    let state = myRef("./data.json");
    // let state=ref([])
    // // 傳入路徑,返回promise
    // fetch('./data.json')
    // .then((res)=>{
    //   return res.json()//為了方便處理轉換成json
    // })
    // .then((data)=>{
    //   // 拿到伺服器返回的資料
    //   console.log(data);
    //   state.value=data
    // })
    // .catch((err)=>{
    //   // 失敗的時候列印
    //   console.log(err);
    // })
    return { state };
  },
};
</script>

//data.json,需要把這注釋刪除
[
    {"id":1,"name":"黃忠"},
    {"id":2,"name":"周瑜"},
    {"id":3,"name":"安其拉"}
]

效果

在這裡插入圖片描述