Vue2与Vue3数据响应式原理的区别

Vue 2 与 Vue 3:响应式原理的差异解析

Vue.js 是一个流行的 JavaScript 框架,用于构建用户界面,从版本 2 到版本 3,其响应式系统发生了重大改进。在本文中,我们将探讨 Vue 2 和 Vue 3 之间响应式原理的不同之处。

Vue 2 响应式原理

在 Vue 2 中,响应性围绕着使用 Object.defineProperty 来定义数据属性的 getter 和 setter。这种机制使得 Vue 能够拦截属性访问和变化,从而能够跟踪依赖关系,并在数据更改时触发重新渲染。

让我们通过一个简单的示例来了解 Vue 2 的响应式机制:

javascript 复制代码
let data = {a: 1, b: 2}
let vm2 = {}
for (let key in data) {
    Object.defineProperty(vm2, key, {
        get: function() {
            console.log(`vue2 get被劫持到了`);
            return data[key];
        },
        set: function(val) {
            console.log(`vue2 set被劫持到了 -> ${val}`);
            data[key] = val;
        }
    })
}

在这段代码中,vm2 是一个空对象,充当 data 的代理。通过使用 Object.defineProperty,Vue 2 拦截属性访问和变化,并通过 getter 和 setter 进行处理。

Vue 3 响应式原理

Vue 3 引入了基于 JavaScript 的 Proxy 对象的更强大的响应式系统。代理提供了一种更灵活和高效的方式来观察和响应对象的变化。让我们看看 Vue 3 是如何利用代理的:

javascript 复制代码
let data2 = {a: 1, b: 2}
let vm3 = new Proxy(data2,  {
    get: function(target, propKey, receiver) {
        console.log(`vue3 get被劫持到了`);
        return Reflect.get(target, propKey, receiver);
    },
    set: function(target, propKey, value, receiver) {
        console.log(`vue3 set被劫持到了 -> ${value}`);
        return Reflect.set(target, propKey, value, receiver);
    }
})

在这里,vm3 是通过 new Proxy() 创建的代理对象。getset 拦截允许 Vue 3 拦截属性访问和变化,类似于 Vue 2,但具有更大的灵活性。

主要区别

  1. 机制 :Vue 2 使用 Object.defineProperty,而 Vue 3 使用 Proxy

  2. 灵活性ProxyObject.defineProperty 提供了更多的灵活性。通过Proxy,Vue 3 可以观察对象和数组的深层次变化,无需像 $set 这样的额外方法。

  3. 性能Proxy通常比 Object.defineProperty 具有更好的性能,特别是在处理大型数据结构时。

  4. 指令 :Vue 3 的响应式系统简化了指令(如 v-model)的实现,使代码更加清晰和高效。

结论

Vue 3 采用了 JavaScript 代理的方式,代表了其响应式系统的重大进步,为开发人员提供了更强大和灵活的工具集,用于构建响应式应用程序。通过了解 Vue 2 和 Vue 3 响应式原理之间的差异,开发人员可以利用每个版本的优势来创建更好的 Vue 应用程序。

完整代码如下

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript" >
        // vue2 响应式原理
        let data = {a:1, b: 2}
        let vm2 = {}
        for(let key in data){
            Object.defineProperty(vm2, key, {
                get: function() {
                    console.log(`vue2 get被劫持到了`);
                    return data[key];
                },
                set: function(val) {
                    console.log(`vue2 set被劫持到了 -> ${val}`);
                    data[key] = val;
                }
            })
        }
        console.log(vm2)
        vm2.b = 3
        // c 无法被劫持 所以vue2需要用$set去解决
        vm2.c = 4
    </script>

    <script type="text/javascript">
        // vue3 响应式原理
        let data2 = {a:1, b: 2}
        let vm3 = new Proxy(data2,  {
            get: function(target, propKey, receiver) {
                console.log(`vue3 get被劫持到了`);
                return Reflect.get(target, propKey, receiver);
            },
            set: function(target, propKey, value, receiver) {
                console.log(`vue3 set被劫持到了 -> ${value}`);
                return Reflect.set(target, propKey, value, receiver);
            }
        })
        console.log(vm3)
        vm3.b = 3
        vm3.c = 3
    </script>
</body>
</html>
相关推荐
uhakadotcom20 分钟前
视频直播与视频点播:基础知识与应用场景
后端·面试·架构
拉不动的猪35 分钟前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪44 分钟前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
uhakadotcom2 小时前
快速开始使用 n8n
后端·面试·github
uhakadotcom2 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom2 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom2 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom2 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom2 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试
探索为何3 小时前
JWT与Session的实战选择-杂谈(1)
后端·面试