整体分析Vue的基本结构如下图所示:(备注:完整代码github地址https://github.com/1512955040/MiniVue)

Vue响应式原理底层代码模拟实现-LMLPHP

上图中,为我们模拟最小vue的整体结构,首先创建一个vue类型,它负责把data中的成员注入到vue实例中,并且转化成getter/setter,observer的作用是数据劫持,对data中的属性进行数据监听,如果数据发生变化会获取到最新的值,并通知dep。Compiler的作用是解析每个元素中的指令和差值表达式并替换成相应的数据。Dep的作用是添加观察者,当数据发生变化时通知所有的观察者。Watcher内部有一个Update方法负责更新视图,下面我们用代码的方式一一进行实现。

1.Vue.js功能:

1-1负责接收初始化的参数(选项)

1-2负责把data中的属性注入到vue实例,转化成getter/setter

1-3负责调用observer监听data中所有属性的变化

1-4负责调用Compiler解析指令/差值表达式

类图结构如下:

Vue响应式原理底层代码模拟实现-LMLPHP

如上图所示:vue类中有三个属性,分别是$options,$el,$data,这三个属性记录构造函数中传过来的参数。_proxyData为vue类中的方法

所以以_开头的成员就是私有成员,这个方法的功能是把data中的属性转化为getter和setter注入到vue实例中。

class Vue{
    constructor(options) {
        //1.通过属性保存选项中的数据
        this.$options = options || {}
        this.$data = options.data || {}
        this.$el = typeof options.el === 'string' ? document.querySelector(options.el) : options.el
        //2.把data中的成员转化为getter和setter,注入到vue实例中
        this._proxyData(this.$data)
        //3.调用observer对象,监听数据的变化
        new Observer(this.$data)
        //4.调用compiler对象,解析指令和差值表达式
        new Compiler(this)
    }
    //把Vue的属性转化为getter和setter,注入到Vue实例中
    _proxyData(data){
        //遍历data中所有属性
        Object.keys(data).forEach(key=>{
          //把data的属性注入到vue实例全局中
          Object.defineProperty(this,key,{
              enumerable:true,
              configurable:true,
              get(){
                return data[key]
              },
              set(newValue){
                if(newValue===data[key]){
                    return
                }
                data[key]=newValue
             }
        })
      })
    }
}
08-16 02:08