vue 對於 mvvm 的實現是基於 Object.defineProperty
來實現的,
對於 es6
而言有另外一種類似的監視物件屬性變化的 api
, 即使用代理 Proxy
對於這個 api
不熟悉的開發者可以點選這裡
利用 porxy
代理物件的 get
, defineProperty
, deleteProperty
方法即可實現,程式碼簡潔明瞭
const watch = (object, onChange) => {
const handler = {
/*
如果 target[property] 為物件時遞迴代理,否則返回屬性值
@param {object} target
@param {string} property
@param {object} [receiver]
*/
get (target, property, receiver) {
try {
return new Proxy(target[property], handler)
} catch (err) {
return Reflect.get(target, property, receiver)
}
},
/*
當物件賦值的時候,觸發的代理方法(如果有 set 代理, 則觸發 set 代理,否則觸發該方法)
@param {object} target
@param {string} property
@param {object} descriptor
*/
defineProperty (target, property, descriptor) {
onChange() // 賦值時觸發回撥函式
return Reflect.defineProperty(target, property, descriptor)
},
/*
當刪除物件屬性時觸發的代理方法
@param {object} target
@param {string} property
*/
deleteProperty (target, property) {
onChange() // 刪除屬性時觸發回撥函式
return Reflect.deleteProperty(target, property)
}
}
return new Proxy(object, handler)
}
// demo
let obj = {
a: 123,
b: {
c: 333
}
}
let i = 0
let watchObj = watch(obj, () => {console.log('Object changed:', ++i)})
watchObj.a = 333
// => 'Object changed: 1'
watchObj.b.c = 444
//=> 'Object changed: 2'
複製程式碼