Vue3.x 中 ref 和 reactive 有何差异?带你一探源码!
2023-10-07 07:05:27
揭秘 Vue3.x 的幕后:ref 与 reactive 的深入探索
Vue3.x 引入了两大革命性的工具,ref 和 reactive,它们极大地提升了 Vue 应用程序的开发效率和响应能力。本文将带领你深入了解这两项技术的原理和实现机制,助你掌握 Vue3.x 开发的精髓。
ref:让 DOM 元素触手可及
ref 就像一把万能钥匙,它可以让你轻松获取 DOM 元素的引用。通过使用 ref,你可以直接操作元素的属性、方法,甚至监听它的事件。
例如,以下代码使用 ref 将一个按钮的引用存储在变量 btnRef
中:
<template>
<button ref="btn">点击我</button>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const btnRef = ref(null); // 保存按钮的引用
return {
btnRef,
};
},
};
</script>
之后,你就可以在 Vue 实例中使用 btnRef
来访问按钮元素了:
this.btnRef.value.addEventListener('click', () => {
console.log('按钮被点击了!');
});
reactive:管理响应式数据,让变化触目可见
reactive 负责管理响应式数据,这意味着当你修改响应式对象中的属性时,Vue 会自动更新视图,让变化瞬间展现在你的眼前。
例如,以下代码将一个对象 obj
转换为响应式对象:
import { reactive } from 'vue';
const obj = reactive({
name: 'John',
age: 30,
});
现在,当我们修改 obj
中的属性时,Vue 会自动更新使用该对象的任何组件。
obj.name = 'Jane'; // Vue 将更新视图中显示的名称
深入源码,揭开实现之谜
为了进一步理解 ref 和 reactive,让我们深入它们的源码中一探究竟。
ref 的实现
export function ref(value) {
const wrapper = {
value,
__v_isRef: true,
};
return wrapper;
}
ref 函数创建一个包装对象,其中包含 value
和一个标记,__v_isRef
,用于标识这是个 ref 对象。
reactive 的实现
export function reactive(obj) {
return createReactive(obj, [], {});
}
function createReactive(obj, shallow, seen) {
// 避免循环引用
if (seen.includes(obj)) {
return obj;
}
// 创建代理对象
const proxy = new Proxy(obj, {
// 拦截获取属性操作
get(target, key, receiver) {
// 追踪依赖关系
track(target, key, receiver);
// 递归处理嵌套对象
if (!shallow && isObject(target[key])) {
return createReactive(target[key], shallow, seen);
}
// 返回属性值
return target[key];
},
// 拦截设置属性操作
set(target, key, value, receiver) {
// 触发更新
if (target[key] !== value) {
target[key] = value;
trigger(target, key, value, target[key]);
}
},
});
return proxy;
}
reactive 函数创建了一个代理对象,该对象负责追踪依赖关系和收集更新。当对象属性发生变化时,代理对象会自动触发更新。
对比 ref 与 reactive
特征 | ref | reactive |
---|---|---|
用途 | 获取 DOM 元素的引用 | 管理响应式数据 |
声明方式 | ref 属性 |
reactive 函数 |
访问方式 | $refs 对象 |
对象本身 |
响应性 | 否 | 是 |
性能 | 相对较快 | 相对较慢 |
常见问题解答
-
什么时候使用 ref?
答:当需要操作 DOM 元素时,例如,获取元素的尺寸、触发元素的事件。 -
什么时候使用 reactive?
答:当需要管理响应式数据时,例如,跟踪表单输入值的变化或创建动态列表。 -
ref 和 reactive 会影响性能吗?
答:是的,过渡使用 ref 和 reactive 会影响性能。在不必要的情况下,避免使用它们。 -
如何避免循环依赖?
答:使用seen
数组来跟踪访问过的对象,防止陷入循环。 -
为什么 reactive 中有
shallow
选项?
答:shallow
选项可以优化性能,仅追踪第一层属性的变化。
结语
ref 和 reactive 是 Vue3.x 中必不可少的工具,它们使我们能够轻松管理 DOM 元素和响应式数据。通过深入了解它们的原理和实现机制,我们可以开发出更高效、更动态的 Vue 应用程序。愿这篇文章为你照亮 Vue3.x 开发的道路,让你创造出令人惊叹的交互式体验。