Vue中MVVM数据双向绑定原理

        vue响应原理是数据劫持结合发布者、订阅者的方式来实现的。通过object.defineProperty来劫持各个属性的settergetter,在数据发生变化的时候发布消息给订阅者,触发响应的监听回调

------object.defineProperty下面会详细讲解


那什么是MVC和MVVM呢?

MVC:即model-view-controller(模型-视图-控制器),是项目的一种分层架构的思想,它把复杂的项目逻辑,抽离成职能单一的小模块,每个模块看似相互独立,其实也是相互依赖的,好处:保证了模块的职能单一性,方便程序的开发、维护、耦合度低

MVVC:即model-view-viewModel(模型-视图-控制器),它是一种数据双向绑定的模式,用viewModel来建立model数据层和view视图层的连接,数据改变会影响视图,视图改变会影响数据

Vue中MVVM数据双向绑定原理_第1张图片上图为官方图解 

具体流程:

第一步:数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新的值并通知订阅者

第二步:指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数

第三步:Watcher作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图

第四步:MVVM作为数据绑定的入口,整合Observer、Compile和watcher三者,通过Observer监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭建起Observer和Compile之间的通信桥梁达到数据双向绑定效果

Objest.defineProperty直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象

语法:Object.defineProperty (obj , prop , descriptor)

参数obj:要定义属性的对象

           prop:要定义或修改的属性的名称或Symbol

           descriptor:要定义或修改的属性描述,也就是配置项(6个)

配置项一value (默认为undefined)

Vue中MVVM数据双向绑定原理_第2张图片 Vue中MVVM数据双向绑定原理_第3张图片

 由图可以看出新添加的属性颜色和上面原有属性颜色不一样(该属性不可枚举)

Vue中MVVM数据双向绑定原理_第4张图片 

 配置项二enumerable(默认为false)

 created() {
        Object.defineProperty(this.obj, 'address', {
          value: '地址',    //该属性对应的值
          enumerable: true,    //是否可枚举
        })
        console.log(this.obj)
      },

Vue中MVVM数据双向绑定原理_第5张图片

 下面我想去更改添加属性的值

 created() {
        Object.defineProperty(this.obj, 'address', {
          value: '地址',
          enumerable: true,
        })
        this.obj.address = 'change地址'    //改变address的值
        console.log(this.obj)
      },

Vue中MVVM数据双向绑定原理_第6张图片

 发现它并不能被改变,下面用第三个配置项去实现

  配置项三writable(默认为false)

 created() {
        Object.defineProperty(this.obj, 'address', {
          value: '地址',  //该属性对应的值
          enumerable: true, //是否可枚举
          writable: true,    //是否可更改
        })
        this.obj.address = 'change地址' //改变address值
        console.log(this.obj)
      },

Vue中MVVM数据双向绑定原理_第7张图片

 下面我们去删除这个属性

Vue中MVVM数据双向绑定原理_第8张图片

 发现这个属性是没有被删除的,下面用第四个配置项去实现

   配置项四configurable(默认为false)

created() {
        Object.defineProperty(this.obj, 'address', {
          value: '地址', //该属性对应的值
          enumerable: true, //是否可枚举
          writable: true, //是否可更改
          configurable: true, //是否可删除
        })
        this.obj.address = 'change地址' //改变address值
        delete this.obj.address
        console.log(this.obj)
      },

Vue中MVVM数据双向绑定原理_第9张图片

 那这样也没实现数据双向绑定啊,下面我们用原生js来讲讲最重要的get和set的配置

 配置项五:get(默认值为undefined)

  

怎么让age与changeAge实现双向绑定呢

  Object.defineProperty(obj, 'age', {
    // get:function(){} 简写为get(){}
      get() {
        return 123
      },
    })

Vue中MVVM数据双向绑定原理_第10张图片

现在将changeAge返回给age

 Object.defineProperty(obj, 'age', {
      get() {
        return changeAge  
      },
    })

此时 age值等于changeAge,但是无法进行修改,它的值会一直为changeAge

  配置项六:set(默认值为undefined)

    Object.defineProperty(obj, 'age', {
      //让age值等于changeAge,但是不写set,他会一直为changeAge值,不会发生改变
      get() {
        return changeAge  
      },
      //使changeAge等于age的值,让age值可以改变
      set(value) {
         return (changeAge = value)  
      },
    })

下面放下测试代码,大家可以运行看看



  
    
    
    
    Document
    
  
  
    


你可能感兴趣的:(vue,javascript,服务器,vue)