MVVM
mode<=view-model=>view
非侵入式
直接修改输入 调用方法才能更新数据(侵入式)
Object.defineProperty()
数据劫持、数据代理,可以设置对象隐藏属性
- writable -true- 是否可改变
- enumerable -false- 是否可遍历
- configurable -false- 属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。
- value -undefined- 正常的属性
- get() 拦截get 不能与value 同时出现 。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。
- set() 拦截set。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。
let object1 = {}
Object.defineProperty(object1, 'property1', {
value: 42,
writable: false // 是否可写
});
Object.defineProperty(object1, 'property2', {
// getter
get() {
console.log('object1.property2-----------------被读')
},
// setter
set(){
console.log('object1.property2-----------------设置')
}
});
// 中转
let temp = ''
Object.defineProperty(object1, 'property3', {
// getter
get() {
// return temp 中转的变量
return 3
},
// setter
set(newVal){
// temp = newVal 中转的变量
}
});
console.log(object1.property2)
object1.property2++
object1.property2 = 10
console.log(object1.property2, '实际未设置')// undefined
object1.property3 = 10
console.log(object1.property3, '修改值依旧返回 固定值,需要用个变量中转')
// defineReactive
let obj = {}
const defineReactive = function (obj, key, val) {
Object.defineProperty(obj, key, {
configurable: true,
enumerable: true,
// getter
get() {
console.log('-----------------访问属性', key, ':', val)
return val
},
// setter
set(data) {
if (val === data) {
return false
}
console.log('-----------------设置属性', key, ':', val)
val = data
}
});
}
defineReactive(obj, 'a', 10)
defineReactive(obj, 'b', 20)
console.log(++obj.a)
console.log(obj.b)