Ref全家桶
1、Vue+TS定義ref資料類型
方法一:
import { ref } from 'vue';
type T = {
name: string | number;
};
// 也可以讓ts自己做類型推導
let message = ref<T>({
name: '111',
});
方法二:對于類型比較複雜vue提供了一個interface
vue内部定義了這個接口
interface Ref<T> {
value: T
}
import { ref } from 'vue';
import type {Ref} from 'vue'
type T = {
name: string | number;
};
// Ref是vue提供的一個interface
let message: Ref<T> = ref({
name: '111',
});
2、手寫customRef
import { customRef } from 'vue';
function MyRef<T>(value: T) {
return customRef((track, trigger) => {
return {
get() {
//收集依賴
track();
return value;
},
set(newVal) {
value = newVal;
// 觸發依賴
trigger();
},
};
});
}
// 使用
const obj = MyRef<string>('1111');
應用場景:防抖
import { customRef } from 'vue';
function MyRef<T>(value: T) {
let timer: any;
return customRef((track, trigger) => {
return {
get() {
//收集依賴
track();
return value;
},
set(newVal) {
clearTimeout(timer);
timer = setTimeout(() => {
value = newVal;
timer = null;
// 觸發依賴
trigger();
}, 300);
},
};
});
}
const obj = MyRef<string>('1111');
3、shallowRef作用:建立一個淺層次的ref,隻會監聽到
.value
變化。
注意:它裡面的值不是響應式的。
let num1: Ref<T> = shallowRef({
name: '111',
});
num1.value.name = '222'//這樣修改頁面不會變化,這個name屬性是非響應式的
num1.value = {name:'2222'}//這樣修改頁面會變化,這樣修改可以被監聽
注意:ref和shallowRef不要混用,ref會使shallowRef也變成生層次的響應資料。
ref和reactive的差別:
- 定義資料角度:
- ref用于定義基本資料類型,
- reactive用于定義引用資料類型
- 注意:ref也能定義引用資料類型,其内部會自動通過reactive轉為代理對象。
- 原理角度:
- ref通過Object.defineProperty()的get與set來實作資料響應式(資料劫持)。
- reactive通過使用Proxy來實作響應式,并通過Reflect操作源對象内部的資料。
- 使用角度:
- ref在操作資料時要.value,在模闆中不用
- reactive在操作資料和模闆中均不用
4、triggerRef函數的作用:接收一個ref對象作為參數,強制更新收集的依賴。
5、isRef函數的作用:接收一個對象作為參數,判斷是不是一個Ref對象。
6、ref在模闆中使用擷取dom元素
<template>
<div ref="dom">111</div>
<button @click="change">修改</button>
</template>
<script setup >
import { ref } from 'vue';
// 定義的變量名要與模闆中的一緻
const dom = ref<HTMLDivElement>();
const change = () => {
console.log(dom.value?.innerText);
};
</script>