Vue2 与 Vue3 响应式原理对比

API不同

  Vue2 使用 Object.defineProperty 方法、 Vue3使用 Proxy 方法

具体

  Object.defineProperty 是监听某一属性 Proxy 是监听对象

  Vue2 只能拦截已有属性 监听不到 新增/删除 数组下标

  Vue3 行为级拦截 不需要逐个定义属性 新增/删除 数组下标都可以监听

 

简单例子 修改页面属性

<body>
    <div>
        数字: <p id="count">8</p>
    </div>
    <button id="btn">+1</button>
</body>
<script>
  window.onload = function() {
        console.log('页面加载完成');
        document.querySelector("#count").innerText = data.count;
    }
    var data = { count: 0 };
</script>

Vue2

 function defineReactive(obj, key, val) {
        var value = val;
        Object.defineProperty(obj, key, {
            enumerable: true,
            configurable: true,
            get: function() {
                console.log('get', key, value);
                return value;
            },
            set: function(newVal) {
                console.log('set', key, newVal);
                value = newVal;
                var el = document.querySelector("#count");
                if (el) el.innerText = newVal;
            }
        });
    }

    defineReactive(data, 'count', data.count);

    // initialize display (in case window.onload uses another variable)
    var el = document.querySelector("#count");
    if (el) el.innerText = data.count;

    document.querySelector("#btn").onclick = function() {
        data.count += 1;
    };

Vue3

 const p = new Proxy(data, {
        get(t,k) {
            console.log('get', k, 't', t);
            return t[k];
        },
        set(t,k,v) {
            console.log('set', k, v);
            t[k] = v;
            document.querySelector("#count").innerText = v;
            return true;
        }
    })

    document.querySelector("#btn").onclick = function() {
        p.count += 1;
    }

 

posted on 2025-11-21 17:33  贲风  阅读(3)  评论(0)    收藏  举报