customRef---建立一個自定義ref
阿新 • • 發佈:2021-01-22
返回一個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":"安其拉"}
]
效果