前言
周所周知Vue2.0是通过Object.defineProperty()来实现对属性的劫持,达到数据驱动的目的(只能够监听定义时的属性,不能监听新加的属性);而Vue3.0是通过Proxy代理对象,在Vue3.0中有两个重要的数据响应式监听方法 ref 和 reactive ,当然这两个方法就是通过Proxy来实现的;
实现
// ref和reactive底层实现
// reactive
function reactive (obj) {
// 首先判断obj的类型
if (typeof obj === 'object') {
if (obj instanceof Array) {
// 如果是数组那么取出数组中的每一个元素,判断每一个元素是否又是对象,如果是对象也需要包装成Proxy
obj.forEach((item, index) => {
if (typeof item === 'object') {
item[index] = reactive(item)
}
})
} else {
// 如若是对象 取出对象中的每一个值 判断对象的属性的值是否又是对象,如果是也需要包装成Proxy
for (let key in obj) {
if (typeof obj[key] === 'object') {
obj[key] = reactive(obj[key])
}
}
}
} else {
console.warn(`您传入的内容: ${obj}不是一个对象`)
}
return new Proxy(obj, {
get (obj, key) {
console.log("获取值")
return obj[key]
},
set (obj, key, value) {
console.log("改变值")
obj[key] = value
return true // 表示当前操作成功 继续执行下一步
}
})
}
// ref
function ref(val) {
return reactive({value: cal})
}
let obj1 = {
name1: 'a',
age: 18,
children: {
name2: 'aa',
age: 19,
children: {
name3: 'aaa',
age: 20
}
}
}
let state = reactive(obj1)
state.name1 = 'b'
state.children.name2 = 'bb'
state.children.children.nae3 = 'bbb'
console.log(state)
Proxy和 defineProperty的不同
- 在Vue2中监听数据变化是t通过遍历给每个属性都添加上set get 方法来进行对属性监听,而Vue3不用遍历直接监控对象,提高了性能;