对--- highlight: a11y-dark

前言

在 Vue 3 中,响应式系统经历了重构,refreactive 成为了响应式编程的两大核心 API。它们看似相似,却承担了不同的角色。理解它们的实现机制,能够帮助我们更好地掌握 Vue 3 的响应式原理,也能在开发中写出更高效、更优雅的代码。

其次,这个问题也算是面试中老生常谈的问题,千篇一律的八股文让你的回答没有亮点,本文从源码角度分析 reactiveref 的区别, 让你在面试中轻松拿捏面试官

ref 和 reactive 的角色区分

reactive 主要用于将对象变成响应式代理,适合复杂的对象和集合类型。 就是 ref 用于包装任意类型的值,包括基本类型,实现响应式引用。

reactive 的源码实现

不知道怎么进行源码阅读的同学,可以看博主之前的文章,已经做了详细介绍,在此就不赘述了~

首先你好这个人那边去。那个你说的这个你们都登记了。嗯但是觉得设置初始的响应式变量

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue Effect Test</title>

    <!-- 引入你本地 clone 的 vue.global.js -->
    <script src="../../../../vue/dist/vue.global.js"></script>
</head>

<body>
    <div id="text"></div>

    <button id="btn">count++</button>

    <script>
        const { reactive, ref, effect } = Vue;

        // 创建响应式数据
        const state = reactive({
            count1: 1,
        });

        const count2 = ref(1);

        // 绑定 effect:依赖收集 + 自动更新
        effect(() => {
            document.getElementById('text').innerText =
                `当前 count 值:${state.count1}, ${count2.value}`;
        });
        document.getElementById('btn').onclick = () => {
            state.count1++;
            count2.value++;
        };
    </script>
</body>
</html>

从下图可以看到createReactiveObject最后返回的是一个 proxy 对象

当我们访问count1属性时,本质是执行reactive模块下的baseHandler.tsBaseReactiveHandle类中的get方法,可以看到track方法是对对象的属性进行依赖收集的

ref源码的实现

ref声明的响应式变量是通过createRef创建的,

createRef返回的是RefImpl实例

当我们通过.value访问ref数据时,触发get操作,可以看到track操作是对value做的响应式(这是和reactive的本质区别),最后get返回value

重点关注RefImplconstructortoReactive方法,toReactive 会判断 value 是对象就调用 reactive(value),不是对象就原样返回

两者的设计哲学与区别

方面reactiveref
支持类型只能代理对象支持基础类型和对象
实现机制Proxy 深度代理getter/setter 包裹 .value
响应式深度访问时懒代理嵌套对象对象 .value 内部递归 reactive
依赖收集Proxy get.value getter
触发更新Proxy set.value setter
使用场景状态对象及复杂数据基础类型值或包裹对象

注意

ref是对value做的响应式,所以watch时候,不到对象属性的改变,得配合deep使用

原创不易,如果对你有帮助,帮忙点攒、收藏、关注~

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com