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;
}
浙公网安备 33010602011771号