ref 相关
ref 相关
ref
函数是 Vue3 中用于创建响应式数据的方法之一,也是 Vue3 响应式系统的核心功能之一,下面我们将探究 ref
函数的用法及实现原理。
使用方法
ref
ref
函数在 Vue3 中的作用是将原始值转化为响应式数据,它的用法非常简单,只需要传入一个原始值作为参数即可。
const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
shallowRef
shallowRef
函数的作用与 ref
函数类似,但是它只对传入的值进行浅层响应式处理,而不会对嵌套的属性进行响应式处理。
const state = shallowRef({
count: 0
});
// 输出 0
watchEffect(()=>console.log(state.value.count));
// 不会触发响应
state.value.count++;
triggerRef
triggerRef
函数的作用是手动触发 shallowRef
对象的响应式更新。
const state = shallowRef({
count: 0
});
// 输出 0
watchEffect(()=>console.log(state.value.count));
state.value.count++;
// 输出 1
triggerRef(state);
customRef
customRef
函数的作用是自定义 ref
对象的响应式处理逻辑,它有两个默认参数,并返回一个带有 get
和 set
方法的对象:
track
:一个函数,用于追踪依赖,在get
方法中使用。trigger
:一个函数,用于触发响应式更新,在set
方法中使用。
const count = customRef((track, trigger) => {
return {
get() {
track();
//这里可以自定义get处理逻辑
console.log("get value")
return value;
},
set(newValue) {
value = newValue;
//这里可以自定义set处理逻辑
console.log("set value")
trigger();
}
};
})
console.log(count.value); // 输出 get value ==> undefined
count.value = 123;
console.log(count.value); // 输出 set value ==> 123
isRef
isRef
函数接收一个参数并返回一个布尔值,用于判断该参数是否为 ref
转化的对象。
const count = ref(0);
console.log(isRef(count)); // true
console.log(isRef(123)); // false
unref
unref
函数接收一个参数并返回该参数的值,如果参数为 ref
对象,则返回该对象的值,否则返回该参数本身。
const count = ref(0);
const countValue = unref(count);
console.log(countValue); // 0
const countValue = unref(123);
console.log(countValue); // 123
toRef
toRef
函数接收两个参数,第一个参数一个响应式对象,第二个参数为属性名,返回一个 ref
对象,该对象的值与传入的对象的属性值相同。
const state = reactive({
count: 0
});
const countRef = toRef(state, 'count');
console.log(countRef.value); // 0
countRef.value++;
console.log(state.count); // 1
toRefs
toRefs
函数接收一个对象作为参数,返回一个对象,该对象的每个属性都是 ref
对象,其值与传入对象的属性值相同。
const state = reactive({
count: 0,
name: 'Vue3'
});
const stateRefs = toRefs(state);
console.log(stateRefs.count.value); // 0
console.log(stateRefs.name.value); // 'Vue3'
stateRefs.count.value++;
console.log(state.count); // 1
实现原理
由于 Proxy
只能代理对象类型的数据,而对于原始类型的数据,如 number
、string
等,Proxy
无法代理,因此 Vue3 引入了 ref
函数来将原始类型的数据转化为响应式数据。
包装数据
ref
函数会将传入的原始值包装成一个带有 value
属性的对象,然后再调用 reactive
函数将这个包装对象转换为响应式数据。
以下是简化版的代码实现:
function ref(value) {
//将传入的原始值包装成为带有value属性的对象
const wrapper = {
value: value
}
//为包装对象设置 __v_isRef 标记,表示这是一个 ref 对象
Object.defineProperty(wrapper, '__v_isRef', {
value: true,
// configurable: false,
// writable: false,
// enumerable: false
});
//调用 reactive 函数将包装对象转换为响应式数据
return reactive(wrapper);
}
由以上代码示例可以理解到为什么使用 ref
创建的响应式数据都需要使用 .value
来访问其值。
参考信息
ref
相关信息