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>
相关推荐
NAGNIP1 小时前
一文搞懂CNN经典架构-DenseNet!
算法·面试
花间相见1 小时前
【MySQL面试题】—— MySQL面试高频问题汇总:从原理到实战,覆盖90%考点
数据库·mysql·面试
野生技术架构师2 小时前
1000道互联网大厂Java岗面试原题解析(八股原理+场景题)
java·开发语言·面试
YuanDaima20482 小时前
[CrewAI] 第15课|构建一个多代理系统来实现自动化简历定制和面试准备
人工智能·python·面试·agent·crewai
NAGNIP3 小时前
一文搞懂CNN经典架构-EfficientNet!
算法·面试
Arya_aa3 小时前
网络:前端向后端发送网络请求渲染在页面上,将EasyMock中的信息用前端vue框架编写代码,最终展示在浏览器
前端·vue.js
Giant1003 小时前
🔥前端跨域封神解法:Vite Proxy + Express CORS,一篇搞定所有跨域坑!
前端·javascript·面试
timi先生4 小时前
语料库全栈项目部署 (Vue + Java + CQPweb)
java·前端·vue.js
Lazy_zheng4 小时前
Map / Set / WeakMap / WeakSet,一次给你讲透
前端·javascript·面试
雨雨雨雨雨别下啦5 小时前
Vue3——RabbitShopping
前端·javascript·vue.js