Observer-代表一个对象,监听数据的变化,即:数据劫持-把$data中的属性设置为getter/setter - 当数据发生改变的时候,要发送通知(
数据劫持——即:监听数据的变化
1.把$data中的属性设置为getter/setter
2.当数据发生改变的时候,要发送通知(发送消息)
observer.js
中
// 数据劫持——即:监听数据的变化
// 1.把$data中的属性设置为getter/setter
// 2.当数据发生改变的时候,要发送通知(发送消息)
function Observer(data) {
this.walk(data)
}
// 遍历data中的所有属性,设置为响应式数据
Observer.prototype.walk = function(data) {
//遍历data中的所有属性
Object.keys(data).forEach(key => {
//设置为响应式数据 data.name\data.age 这些是固定属性,可直接写;但key属性是变化的,是变量,需用中括号[] data['name']=data.name
this.defineReactive(data, key, data[key])
})
}
// 把属性设置为getter setter 3个参数 对象 属性 值
Observer.prototype.defineReactive = function(data, key, value) {
Object.defineProperty(data, key, {
// 不可以配置 不可配置
configurable: false,
// 可以遍历 可枚举
enumerable: true,
get() {
console.log('observer get', key)
// 千万不能调用 data[key] 会出现类似死循环的事情
// return data[key]
return value
},
set(newValue) {
//新旧值一样
if (newValue === value) {
return
}
value = newValue
// 当数据改变,发送通知(消息)
// 事件的名字是属性的名字
em.$emit(key)
}
})
}
代码实现:
1.Observer(data)
Observe()接收一个data的参数
2.walk()的方法里面遍历data的所有属性,并把属性设置为响应式数据
3.Observer是一个构造函数,测试时:
- 需要在vue.js中创建一个实例
//数据劫持,把data中的成员设置为setter/getter
new Observer(this.$data)
- 在index.html中引入
compiler.js
文件
<script src="./MVVM/observer.js"></script>
**测试:**打开index.html文件,在控制台进行操作
输入 vm,$data发生了变化
输入vm.name,访问name的值,验证执行逻辑:
当访问name的值时:
1.先执行vue.js文件中的get方法;
2.该get方法中去访问$data[key]的属性
3. data[key]会触发observer.js文件中的get()方法
4.把该get()方法中的value值return返回出去
注:
vue.js中的get仅仅是一种简化,真正的值在data中,observer.js就是处理data的
操作3个文件:vue.js\observer\index.html,打印显示如下:
或
设置断点进行验证,也可以得到name的值所执行的逻辑流程