vue原理之observer
上节课我们讲了vue五种类型中的vue 实现data响应这节课我们讲第二中类型observerObserver功能负责把 data 选项中的属性转换成响应式数据data 中的某个属性也是对象,把该属性转换成响应式数据数据变化发送通知具体代码实现如下class Observer {constructor(data) {this.walk(data)}// 1. 判断数据是否是对象,如果不是对象返回
·
上节课我们讲了vue五种类型中的vue 实现data响应
这节课我们讲第二中类型observer
Observer
功能
负责把 data 选项中的属性转换成响应式数据
data 中的某个属性也是对象,把该属性转换成响应式数据
数据变化发送通知
具体代码实现如下
class Observer {
constructor(data) {
this.walk(data)
}
// 1. 判断数据是否是对象,如果不是对象返回
// 2. 如果是对象,遍历对象的所有属性,设置为 getter/setter
walk(data) {
if (!data || typeof data != 'object') {
return
}
Object.keys(data).forEach(key => {
this.defineReactive(data, key, data[key])
})
}
// 定义响应式成员 即对data总的数据实现setter和getter
defineReactive(data, key, val) {
const that = this
// 如果 val 是对象,继续设置它下面的成员为响应式数据
this.walk(val)
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get() {
return val;
},
set(newValue) {
if (val === newValue) {
return
}
// 如果 newValue 是对象,设置 newValue 的成员为响应式
that.walk(newValue)//这里不用this 因为在set方法中 在function的内部 会开启新的作用域 此时的this执行data对象
val = newValue;
}
})
}
}
整体代码如下:
// 具体实现步骤
// 1: 通过属性 保存选项的数据
// 2: 把data中的成员 转换为getter和setter 注入到vue实例中 方便使用
// 3:调用observer对象 监听数据变化
// 4:调用compiler 解析指令和插值表达式
class Vue {
constructor(options) {
// 通过属性 保存选项的数据
this.$options = options || {};//如果我们在调用vue构造函数的时候 没有传入参数 我们初始化一个空对象
this.$data = options.data || {};
this.$el = typeof options.el === 'string' ? document.querySelector(options.el) : options.el;//如果我们是传入的选择器 则将选择器转换为dom对象
// 把data中的成员 转换为getter和setter 注入到vue实例中 方便使用
this._proxyData(this.$data)
// 调用observer对象 监听数据变化
new Observer(this.$data)
// 调用compiler 解析指令和插值表达式
}
_proxyData(data) {//vue传过来的参数 转换为getter和setter
// 遍历data的所有属性
Object.keys(data).forEach(key => {
Object.defineProperty(this, key, {
// 可遍历 可枚举
enumerable: true,
configurable: true,
get() {
return data[key]
},
set(newValue) {
if (newValue === data[key]) {
return
} else {
data[key] = newValue;
}
}
})
})
// 把data中的属性 注入到vue实例中
}
}
class Observer {
constructor(data) {
this.walk(data)
}
// 1. 判断数据是否是对象,如果不是对象返回
// 2. 如果是对象,遍历对象的所有属性,设置为 getter/setter
walk(data) {
if (!data || typeof data != 'object') {
return
}
Object.keys(data).forEach(key => {
this.defineReactive(data, key, data[key])
})
}
// 定义响应式成员 即对data总的数据实现setter和getter
defineReactive(data, key, val) {
const that = this
// 如果 val 是对象,继续设置它下面的成员为响应式数据
this.walk(val)
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get() {
return val;
},
set(newValue) {
if (val === newValue) {
return
}
// 如果 newValue 是对象,设置 newValue 的成员为响应式
that.walk(newValue)//这里不用this 因为在set方法中 在function的内部 会开启新的作用域 此时的this执行data对象
val = newValue;
}
})
}
}
let vm = new Vue({
el: '#app',
data: {
msg: 'hello',
count: 123,
person: {
name: 'zs'
}
}
})
vm.msg={'sex':'ada'}
上一篇:vue原理代码的基本实现
下一篇:详解vue原理中的编译compiler
更多推荐
已为社区贡献1条内容
所有评论(0)