使用這個屬性,能夠監視 data 中指定數據的變化,而後觸發這個 watch 中對應的 function 處理函數函數
getter:當獲取(get)一個對象的某個屬性時執行的方法ui
setter:當設置(set)一個對象的某個屬性時執行的方法this
getter 和 setter 不須要咱們手動去調用,只要咱們對這個數據進行了操做,那這連個方法就會自動調用spa
(function () {
var o = { a: 1}
Object.defineProperty(o, 'b', {
get: function() {
console.log('get') // 只有調用o.b時纔會輸出get
return this.a
},
set: function(val) {
this.a = val
},
configurable: true
})
// 此處雖然調用o.b,輸出的倒是o.a的值
console.log('a', o.a, 'b', o.b); // a 1 b 1
o.b = 2 // 給o.b賦值,實際上是賦值給了o.a
console.log(o.a) // 2
// o始終只有a一個屬性
console.log(o) // {a: 2}
})()
複製代碼
// 定義watcher對象
class watcher {
constructor (opts) {
this.$data = this.getBaseType(opts.data) === 'Object' ? opts.data : {}
this.$watch = this.getBaseType(opts.watch) === 'Object' ? opts.watch : {}
console.log(opts.data, opts.watch)
// 遍歷data的全部屬性
for (let key in opts.data) {
console.log('key', key) // key a key b
this.setData(key, opts.data[key])
}
}
getBaseType (target) {
// 判斷取數據類型
const typeStr = Object.prototype.toString.call(target)
return typeStr.slice(8, -1)
}
setData(_key, _value) {
console.log(_key, _value) // a 0 b hello
// this: Object.defineProperty(this) 把上下文指向當前的對象
Object.defineProperty(this, _key, {
get: function () {
console.log(_key) // b a
return this.$data[_key]
},
// val是新的值
set: function (val) {
console.log('val', val, '_value', _value); // val 7 _value 0
const oldVal = this.$data[_key]
if (oldVal === val) return val // 值相同,不更新
this.$data[_key] = val // 更新
console.log(_key, this.$data[_key]) // a 7
this.$watch[_key] && typeof this.$watch[_key] === 'function' && this .$watch[_key].call(this, val, oldVal)
return val
}
})
}
}
let vm = new watcher({
data: {
a: 0,
b: 'hello'
},
watch: {
// 處理函數
// 一旦data.a的值發生改變則執行watch[a]()
a(newVal, oldVal) {
console.log('new', newVal, 'old', oldVal) // new 7 old 0
}
}
})
console.log(vm.b) // hello
setTimeout(() => {
console.log(vm.a = 7) // 7
console.log('vm.a', vm.a) // vm.a 7
}, 3000)
複製代碼
輸出:
{ a: 0, b: 'hello' } { a: [Function: a] }
key a
a 0
key b
b hello
b
hello
------------- 3s後 -------------
val 7 _value 0
a 7
new 7 old 0
7
a
vm.a 7複製代碼