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>
相关推荐
北极糊的狐16 小时前
Vue3 中父子组件传参是组件通信的核心场景,需遵循「父传子靠 Props,子传父靠自定义事件」的原则,以下是资料总结
前端·javascript·vue.js
看到我请叫我铁锤17 小时前
vue3中THINGJS初始化步骤
前端·javascript·vue.js·3d
Dream it possible!17 小时前
LeetCode 面试经典 150_图_克隆图(90_133_C++_中等)(深度优先:DFS)
c++·leetcode·面试·
谢尔登17 小时前
defineProperty如何弥补数组响应式不足的缺陷
前端·javascript·vue.js
涔溪18 小时前
实现将 Vue2 子应用通过无界(Wujie)微前端框架接入到 Vue3 主应用中(即 Vue3 主应用集成 Vue2 子应用)
vue.js·微前端·wujie
T***u33319 小时前
前端框架在性能优化中的实践
javascript·vue.js·前端框架
jingling55520 小时前
vue | 在 Vue 3 项目中集成高德地图(AMap)
前端·javascript·vue.js
油丶酸萝卜别吃20 小时前
Vue3 中如何在 setup 语法糖下,通过 Layer 弹窗组件弹出自定义 Vue 组件?
前端·vue.js·arcgis
J***Q2921 天前
Vue数据可视化
前端·vue.js·信息可视化
JIngJaneIL1 天前
社区互助|社区交易|基于springboot+vue的社区互助交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·社区互助