函数ref和toRefs,以及computed
模拟实现ref函数
- ref的使用
- 它接收一个参数,可以是原始类型值也可以是对象,
- 如果传入的是对象,并且这个对象是ref创建的对象,那直接返回。
- 如果是普通对象的话,它内部会调用reactive来创建响应式对象
- 否则对的话创建一个只有value属性响应式对象
- 返回创建的响应式对象
- ref函数的定义
- 代码如下:
function convert(target) { return isObject(target) ? reactive(target) : target; } export function ref(raw) { // 判断raw 是否是由ref创建的响应式对象,如果是对的话直接返回 if (isObject(raw) && raw.__v_isRef) { return raw; } let value = convert(raw); const r = { __v_isRef: true, get value() { track(r, 'value'); return value; }, set value(newValue) { if (newValue !== value) { raw = newValue; value = convert(raw); trigger(r, 'value'); } }, }; return r; }
ref与 reactive的区别
ref可以把基本类型的数据,转换成响应式对象,当获取数据时要使用value属性,模版中使用的时候可以省略value。而 reactive不能把基本类型的数据转换成响应式对象。- ref返回的对象,重新给value属性赋值成对象以后也是响应式的。代码中是通过convert逻辑来处理的。
- reactive 返回的对象,重新赋值以后会丢失响应式,因为重新赋值的对象不再是代理对象。
- reactive 返回的对象不可以解构,如果想要解构的话,需要使用toRefs函数来处理reactive返回的对象。
- 如果一个对象中的成员比较多的时候,使用ref并不方便,因为要取值总要带着value属性。如果一个函数内部只有一个响应式数据,这个时候使用ref会比较方便。因为可以直接解构返回。

模拟实现toRefs函数
toRefs的作用
- 它接收一个reactive返回的响应式对象proxy,也就是Proxy对象。如果传入的的参数不是reactive创建的响应式对象,直接返回。
- 把传入对象的所有属性转换成一个类似于ref返回的对象,根据proxy的类型创建一个新的同类型的对象作为函数返回值,把转换后的属性挂载到一个新的对象上并将其返回。
toRefs的实现
- toRefs的执行逻辑
- toRefs的函数定义:
export function toRefs(proxy) {
// 判断proxy是否是reactive创建的对象。这里因为我们的的reactive没有添加标记,暂时忽略此步骤
// 根据proxy是否为数组类型,创建一个返回对象
const ret = proxy instanceof Array ? new Array(proxy.length) : {};
// 遍历proxy的每一给属性,将其转换成ref返回的对象,并一一挂载到新对象ret上
for (const key in proxy) {
ret[key] = toProxyRef(proxy, key);
}
return ret;
}
function toProxyRef(proxy, key) {
const r = {
__v_isRef: true,
get value() {
return proxy[key];
},
set value(newValue) {
proxy[key] = newValue;
},
};
return r;
}
模拟实现computed函数
computed的作用
- computed接收一个有返回值的函数作为参数getter,这个函数的返回值就是计算属性的值。并且我们要监听这个函数内部使用的响应式数据的变化,最后把这个函数执行的结果返回。
- computed函数内部会通过effect监听getter内部的响应式数据的变化。因为在effect中,执行getter的时候访问响应式数据的属性,会去收集依赖。
- 当数据变化后会重新之心effect函数。把getter的结果再存储到result中。
computed函数的定义
export function computed(getter) { const result = ref(); effect(() => (result.value = getter())); return result; }
至此,Vue.js 3.0的响应式原理就已经介绍完了。
版权声明:本文为u011024243原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。