/*Object的变化侦测*/
//对象的属性拦截
function defineReactive(data,key,val){
if(typeof val === 'object'){
new Observer(val)
}
let dep = new Dep();
Object.defineProperty(data,key,{
enumerable:true,
configurable:true,
get:function(){
// console.log(1)
dep.depend()
return val;
},
set:function(newVal){
// console.log(2)
if(val === newVal){
return
}
val = newVal
dep.notify()
}
})
}
//依赖收集在哪里
class Dep{
constructor(){
this.subs = [];
}
addSub(sub){
this.subs.push(sub)
}
removeSub(sub){
remove(this.subs,sub)
}
depend(){
if(window.target){
this.addSub(window.target)
}
}
notify(){
// console.log("3-1")
// console.log(this.subs)
const subs = this.subs.slice()
// console.log(subs)
for(let i =0;i <subs.length;i++){
subs[i].update()
}
}
}
function remove(arr,item){
if(arr.length){
const index = arr.indexOf(item)
if(index >-1){
return arr.splice(index,1)
}
}
}
//依赖类
class Watcher {
constructor(vm,expOrFn,cb){
// console.log("2-1")
//vm是数据对象value
//expOrFn是key
//cb是回调函数
this.vm = vm;
this.getter = parsePath(expOrFn);
//this.getter为返回函数A
this.cb = cb;
this.value = this.get();
}
get(){
// console.log(this)
window.target = this;
let value = this.getter.call(this.vm,this.vm)
window.target = undefined;
return value
}
update(){
// console.log("update")
// console.log(this)
const oldValue = this.value;
// console.log(oldValue)
this.value = this.get();
// console.log(this.value)
this.cb.call(this.vm,this.value,oldValue)
}
}
const bailRE = /[^\w.$]/;
function parsePath(path){
if(bailRE.test(path)){
return
}
const segments = path.split('.')
//返回函数A 闭包函数
return function(obj){
//obj为数据对象value
//segments为key
// console.log("2-2")
// console.log(obj)
// console.log("-----")
// console.log(segments)
for(let i =0;i <segments.length;i++){
// console.log("2-3")
if(!obj)return
// console.log("2-4")
obj = obj[segments[i]]
}
// console.log("2-5")
// console.log(obj)
return obj
}
}
//侦测所有的key
class Observer {
constructor(value){
this.value = value;
if(!Array.isArray(value)){
this.walk(value)
}
}
walk(obj){
const keys = Object.keys(obj)
for(let i = 0;i<keys.length;i++){
defineReactive(obj,keys[i],obj[keys[i]])
}
}
}
//vue类
class Vue{
constructor(options){
new Observer(options)
//给数据添加订阅者
Object.keys(options).forEach(key=>{//按照options的属性循环实例化watcher
new Watcher(options,key,()=>{
console.log("这是回调方法")
});
})
}
}
let obj = {
time:"12",
hour:"21",
secend:20,
street:"灵魂",
};
new Vue(obj)
obj.time = "17";
/**
* 数据初始化首先 实例化Obsever 并将对象数据作为参数传入 在observer实例中循环参数
* 对象的值value,并对value调用defineReactive方法中实例化Dep 之后重新定义get和set。
* get方法中收集依赖 set方法中派发依赖
* 其次循环数据value 给value添加订阅者 并通过数据项get方法将value 加入dep实例中
*
* **/
console