for(let i = 0; i < keys.length; i++){
//new一个Watcher的实例,
new Watcher(this,keys[i],watch[keys[i]])
}
}
}
initComputed(){
let computed = this.$options.computed
//判断如果存在计算属性,进行遍历
if(computed){
let keys = Object.keys(computed)
for(let i = 0; i < keys.length; i++) {
//传入第四个参数,computed是惰性的
const watcher = new Watcher(this,computed[keys[i]],function() {},{lazy:true})
//把该属性添加到vue实例上,并设置只能取,不能存
Object.defineProperty(this,keys[i],{
enumerable:true,
configurable:true,
get : function computerGetter() {
if(watcher.dirty) {
watcher.get()
watcher.dirty = false
}
//返回出去
return watcher.value
},
set : function computedSetter() {
console.warn(‘请不要给计算属性computed赋值’)
}
})
}
}
}
//实例对象上挂载一个和watch同样的方法
$watch(key,cb) {
new Watcher(this,key,cb)
}
//实现$set方法
$set(target,key,value){
//新增的属性也变成响应式的
defineReactive(target,key,value)
//执行
target.ob.dep.notify()
}
}
//判断类型的函数observe
/**
-
@param {*} data
*/
function observe(data) {
//判断data的数据类型
let type = Object.prototype.toString.call(data)
//如果是基本类型就直接返回
if(type !== ‘[object Object]’ && type !== ‘[object Array]’){
return
}
if(data.ob){
return data.ob
}
//如果是复杂类型,new一个实例
return new Observer(data)
}
//创建一个观察值类,观察data中的数据变化
class Observer {
constructor(data) {
//数组不能使用Object.defineProperty,下标会乱 ,需要判断一下
if(Array.isArray(data)){
data.proto = ArrayMethods
//初始化
this.observeArray(data)
}else{
//调用函数
this.walk(data)
}
//实现$set需要重新new一个Dep实例
this.dep = new Dep()
//在data中新增一个__ob__属性,设置该属性不可遍历
Object.defineProperty(data,‘ob’,{
value:this,
//不可遍历
enumerable:false,
configurable:true,
writable:true
})
}
//walk函数
walk(data) {
let keys = Object.keys(data)