1.1 如何实现响应式数据
数组和对象类型当值变化时如何劫持到。对象内部通过defineReactive方法,使用Object.defineProperty将属性进行劫持(只会劫持已经存在的属性),数组则是通过重写数组方法来实现。 多层对象是通过递归来实现劫持。Vue3则采用 proxy
1.2 vue2 处理缺陷
- 在
Vue2的时候使用defineProperty来进行数据的劫持, 需要对属性进行重写添加getter及setter性能差。 - 当新增属性和删除属性时无法监控变化。需要通过
$set、$delete实现 - 数组不采用
defineProperty来进行劫持 (浪费性能,对所有索引进行劫持会造成性能浪费)需要对数组单独进行处理。 - 对于
ES6中新产生的 Map、Set 这些数据结构不支持。
1.3 Vue2 与 Vue3 实现对比
Vue2
function defineReactive(target,key,value){
observer(value);
Object.defineProperty(target,key,{ ¸v
get(){
//依赖收集
return value;
},
set(newValue){
if (value !== newValue) {
value = newValue;
observer(newValue)
}
}
})
}
function observer(data) {
if(typeof data !== 'object'){
return data
}
// 依赖更新
for(let key in data){
defineReactive(data,key,data[key]);
}
}
vue3
let handler = {
get(target, key) {
if (typeof target[key] === "object") {
return new Proxy(target[key], handler)
}
return Reflect.get(target, key)
},
set(target, key, value) {
let oldValue = target[key]
if (oldValue !== value) {
return Reflect.set(target, key, value)
}
return true
},
}
let proxy = new Proxy(obj, handler)