使用这个属性,能够监视 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复制代码