Vue2实现双向数据绑定的原理是Object.defineProperty的setter和getter属性
下面以劫持对象为例
Object.defineProperty有三个参数分别是要劫持的对象,要劫持的属性,和一个选项对象
选项对象里有
valueVue2实现双向数据绑定的原理是Object.defineProperty的setter和getter属性
下面以劫持对象为例
Object.defineProperty有三个参数分别是要劫持的对象,要劫持的属性,和一个选项对象
选项对象里有
- value 值 当有get和set时不可用,否则报错
- writable 可写 值为true和false 当有get和set时不可用,否则报错
- enumerable 可读 值为true和false
- configurable: false, 可以删除吗
Object.defineProperty(obj, 'name', {
value: "张三", // 值 当有get和set时不可用,否则报错
writable: false, // 可写也就是可以改变吗 当有get和set时不可用,否则报错
enumerable: true, // 可读也就是可以进行访问吗
configurable: false, // 可以删除吗
})
还有两个方法
- set 读取属性时调用
- get 设置属性时调用
Object.defineProperty(obj, 'name', {
// value: "张三", // 值 当有get和set时不可用,否则报错
// writable: false, // 可写也就是可以改变吗 当有get和set时不可用,否则报错
enumerable: true, // 可读也就是可以进行访问吗
configurable: false, // 可以删除吗
get() { // 读取属性时调用
return '我是' + objName
},
set(val) { // 设置属性时调用
objName = val
}
})
在vue2中对一个对象中所有的属性进行了遍历,当读取属性是就会调用get方法,设置属性时就会调用set方法
let obj = {} // 定义一个对象
class Vue { // 定义一个类
$options; // 在类里面定义两个属性
_data;
constructor(options) { // 使用constructor给在类里定义的属性赋值
this.$options = options
this._data = options.data
this.initDate() // 因为构造函数不需要调用,在实例化时会自己调用
}
initDate() {
let keys = Object.keys(this._data) // 对一个对象进行循环获取键名形成的数组
// console.log(keys);
for (let i in keys) { //对这个数组用 for in 进行循环
let key = keys[i] // 把对应的键名赋值给key
Object.defineProperty(this, key, { // 用 Object.defineProperty 进行数据劫持 this代表vm key代表属性名
get() {
// return this[key]._data
return this._data[key] // 把劫持到的属性值在进行读取时返回出去
},
set(val) {
this[key] = val // 在进行设置时劫持数据赋值到vm里
}
})
}
}
}
let vm = new Vue({
data: { name: "张三", age: 21 }
})
console.log(vm.name);