Vue.js通过数据劫持结合发布者-订阅者模式实现数据检测,核心是利用Object.defineProperty()方法:
// 简化版实现原理
const data = { message: 'Hello' };
Object.defineProperty(data, 'message', {
get() {
console.log('获取数据');
return value;
},
set(newVal) {
console.log('更新数据');
value = newVal;
// 触发视图更新
}
});
Vue3使用ES6的Proxy替代Object.defineProperty,解决了以下问题:
computed: {
reversedMessage() {
return this.message.split('').reverse().join('');
}
}
watch: {
message(newVal, oldVal) {
console.log(`数据从${oldVal}变为${newVal}`);
}
}
watch: {
obj: {
handler(newVal) {
// 处理变化
},
deep: true,
immediate: true
}
}
Q:数组变化检测不到?
A:使用Vue.set()或数组的变异方法(push/pop等)
Q:动态添加属性无效?
A:使用Vue.set()或提前在data中声明
Q:性能突然变慢?
A:检查是否监听了大型对象或频繁触发watch