一、reactive
將一個(gè)Object類型的數(shù)據(jù)轉(zhuǎn)換成響應(yīng)式數(shù)據(jù):Proxy實(shí)例
- 直接取屬性值,屬性值不是響應(yīng)式的
- 只能接受Object類型的參數(shù)
import { reactive } from 'vue'
// 響應(yīng)式狀態(tài)
const state = reactive({
count: 0
})
// 打印count的值
console.log(state.count)
reactive的響應(yīng)原理
通過將Object轉(zhuǎn)換成Proxy對(duì)其進(jìn)行攔截
二、ref
ref( target )函數(shù)可以在任何地方將變量變成響應(yīng)式
- 將變量變成一個(gè)包含value屬性的RefImpl對(duì)象。
JS中獲取和設(shè)置時(shí)都要通過變量的value屬性,而在html template中則直接使用變量
import { ref } from 'vue'
const counter = ref(0)
console.log(counter) // { value: 0 }
console.log(counter.value) // 0
counter.value++
console.log(counter.value) // 1
- 可以接受任何類型的參數(shù)。
如果原始變量target為普通變量,value = target,如果target為對(duì)象,value為Proxy(target)
const convert = (val) => isObject(val) ? reactive(val) : val;
ref響應(yīng)原理
ref實(shí)際是通過引用的概念達(dá)到響應(yīng)的目的,無論何處用到變量實(shí)際上通過引用的方式指向同一個(gè)變量

image
三、toRef
toRef(target, property)將響應(yīng)式對(duì)象的某個(gè)屬性變?yōu)轫憫?yīng)式
- target為一個(gè)響應(yīng)式對(duì)象
- 返回一個(gè)包含value的ObjectRefImpl對(duì)象,value為target[property]的引用
const state = reactive({
foo: 1,
bar: 2
})
// state.foo 類型為 number,不具有響應(yīng)式的功能
// 通過toRef可以將其變?yōu)轫憫?yīng)式
const fooRef = toRef(state, 'foo')
fooRef.value++
console.log(state.foo) // 2
state.foo++
console.log(fooRef.value) // 3
當(dāng)您要將 prop 的 ref 傳遞給復(fù)合函數(shù)時(shí),toRef 很有用:
export default {
setup(props) {
useSomeFeature(toRef(props, 'foo'))
}
}
四、toRefs
對(duì)每個(gè)屬性調(diào)用toRef(),將一個(gè)響應(yīng)式對(duì)象的所有屬性轉(zhuǎn)換為響應(yīng)式
當(dāng)從合成函數(shù)返回響應(yīng)式對(duì)象時(shí),toRefs 非常有用,這樣消費(fèi)組件就可以在不丟失響應(yīng)性的情況下對(duì)返回的對(duì)象進(jìn)行分解/擴(kuò)散:
function useFeatureX() {
const state = reactive({
foo: 1,
bar: 2
})
// 邏輯運(yùn)行狀態(tài)
// 返回時(shí)轉(zhuǎn)換為ref
return toRefs(state)
}
export default {
setup() {
// 可以在不失去響應(yīng)性的情況下破壞結(jié)構(gòu)
const { foo, bar } = useFeatureX()
return {
foo,
bar
}
}
}