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>
相关推荐
大鱼前端21 分钟前
Vue 3.5 :新特性全解析与开发实践指南
vue.js
_龙衣1 小时前
将 swagger 接口导入 apifox 查看及调试
前端·javascript·css·vue.js·css3
夏之小星星3 小时前
el-tree结合checkbox实现数据回显
前端·javascript·vue.js
琉璃℡初雪4 小时前
vue2/3 中使用 @vue-office/docx 在网页中预览(docx、excel、pdf)文件
vue.js·pdf·excel
chenyuhao20245 小时前
链表的面试题4之合并有序链表
数据结构·链表·面试·c#
拖孩6 小时前
【Nova UI】十五、打造组件库之滚动条组件(上):滚动条组件的起步与进阶
前端·javascript·css·vue.js·ui组件库
苹果电脑的鑫鑫6 小时前
element中表格文字剧中可以使用的属性
javascript·vue.js·elementui
Hejjon6 小时前
Vue2 elementUI 二次封装命令式表单弹框组件
前端·vue.js
Wannaer7 小时前
从 Vue3 回望 Vue2:响应式的内核革命
前端·javascript·vue.js
赵大仁8 小时前
React vs Vue:点击外部事件处理的对比与实现
javascript·vue.js·react.js