Vue3.0文件學習心得--響應式工具
let foo: unknown //返回值是一個型別判定 (type predicate),這意味著 isRef
可以被用作型別守衛。
if (isRef(foo)) {
// foo 的型別被收窄為了 Ref<unknown>
foo.value
}
2.isProxy:檢查一個物件是否是由 reactive()
、readonly()
、shallowReactive()
或 shallowReadonly()
建立的代理。
( reactive()
、readonly()
、shallowReactive()
或 shallowReadonly()
的原理是在外層包裹proxy)
3.isReactive:檢查一個物件是否是由 reactive()
或 shallowReactive()
建立的代理。
4.isReadonly():檢查傳入的值是否為只讀物件。只讀物件的屬性可以更改,但他們不能通過傳入的物件直接賦值。
通過 readonly()
和 shallowReadonly()
建立的代理都是隻讀的,因為他們是沒有 set
函式的 computed()
ref。
5.unref():如果引數是 ref,則返回內部值,否則返回引數本身。這是 val = isRef(val) ? val.value : val
計算的一個語糖。
6.toRef():基於響應式物件上的一個屬性,建立一個對應的 ref。這樣建立的 ref 與其源屬性保持同步:改變源屬性的值將更新 ref 的值,反之亦然。
(1)使用示例:
const state = reactive({ foo: 1, bar: 2 }) const fooRef = toRef(state, 'foo') //針對的是屬性,而物件
// 更改該 ref 會更新源屬性 fooRef.value++ console.log(state.foo) // 2 // 更改源屬性也會更新該 ref state.foo++ console.log(fooRef.value) // 3
(2)注意事項
2.1 不等同於const fooRef = ref(state.foo),這個 ref()
接收到的是一個純數值。
2.2 與props配合使用時,禁止對 props 做出更改的限制依然有效。嘗試將新的值傳遞給 ref 等效於嘗試直接更改 props,這是不允許的。在這種場景下,你可能可以考慮使用帶有 get
set
的 computed
替代。(可以通過toref取出
props,但不允許對其進行賦值等操作等)
import { toRefs, toRef } from 'vue' export default { setup(props) { //要具有響應式的解構props,需要使用toRef解構props // 將 `props` 的單個屬性轉為一個 ref const title = toRef(props, 'title') } }
2.3即使源屬性當前不存在,toRef()
也會返回一個可用的 ref。這讓它在處理可選 props 的時候格外實用,相比之下 toRefs
就不會為可選 props 建立對應的 refs。
7.toRefs():將一個響應式物件轉換為一個普通物件,這個普通物件的每個屬性都是指向源物件相應屬性的 ref。每個單獨的 ref 都是使用 toRef()
建立的。
(1)使用示例:
const state = reactive({ foo: 1, bar: 2 }) const stateAsRefs = toRefs(state) /* stateAsRefs 的型別:{ foo: Ref<number>, bar: Ref<number> } */ // 這個 ref 和源屬性已經“連結上了” state.foo++ console.log(stateAsRefs.foo.value) // 2 stateAsRefs.foo.value++ console.log(state.foo) // 3
(2)如同toRef中所說具有結構而不失去響應性,經常用在組合式函式中返回響應式物件。
function useFeatureX() { const state = reactive({ foo: 1, bar: 2 }) // ...基於狀態的操作邏輯 // 在返回時都轉為 ref return toRefs(state) } // 可以解構而不會失去響應性 const { foo, bar } = useFeatureX()
(3)toRefs
在呼叫時只會為源物件上可以列舉的屬性建立 ref。如果要為可能還不存在的屬性建立 ref,請改用 toRef
。
對應toRef中的2.3所說的點。