Vue的MVVM

听说Vue用的是MVVM框架,没有特别理解。故做此笔记:

一:什么是MVVM?

  • 概念介绍
    • MVVM分为三个部分:分别是M(Model,模型层 ),V(View,视图层),VM(ViewModel,V与M连接的桥梁,也可以看作为控制器
      1、 M:模型层,主要负责业务数据相关;
      2、 V:视图层,顾名思义,负责视图相关,细分下来就是html+css层
      3、 VM:V与M沟通的桥梁,负责监听M或者V的修改,是实现MVVM双向绑定的要点;
    • MVVM支持双向绑定,意思就是当M层数据进行修改时,VM层会监测到变化,并且通知V层进行相应的修改,反之修改V层则会通知M层数据进行修改,以此也实现了视图与模型层的相互解耦;
  • 关系图

 

二:Vue中通过Object.defineProperty实现MVVM模式

Object.defineProperty的含义:可以在一个对象中定义或者修改一个属性,然后返回这个对象,并且可对该属性的可写入可遍历性存取描述符(get、set)等进行设定;

Object.defineProperty(obj, prop, descriptor)的参数解析:

  • obj: 需要进行定义或修改属性的对象;
  • prop: 需要进行定义或者修改的属性;
  • descriptor: 该属性的描述符(包含存取描述符和数据描述符),该参数以一个对象的形式传入,该参数有六个选项:

               1、value: 设定该属性的值;

               2、writable:该属性是否可写入(是否可改变其value);结果为布尔值;

               3、enumeration:该属性是否可被遍历得到;结果为布尔值;

               4、configurable: 设定该属性是否可被删除,且除writable外的其他描述符是否可被修改;结果为布尔值;

                5、set函数:该属性的值被设置时执行的回调函数,默认为undefined;

                6、get函数:该属性的值被获取时执行的回调函数(例如console.log(prop)),默认为undefined;

             

           注:数据描述符和存取描述符的理解:

              在descriptor的六个选项中,有数据描述符和属性描述符,他们是不可共存的,否则会报错(因为功能上有所重复和冲            突),其中:

             1、 数据描述符:value和writable;

             2、存取描述符: set 和 get;

             3、数据/存取描述符共用:configurable,enumerable;

       报错的例子如下: 

    

兼容性:只能在iE8以上

三:使用Object.defineProperty实现MVVM的表单数据双向绑定

  有这么一个表单和一个person对象:

  

  • 需要实现的功能(该表单与person对象的双向绑定)
    • 1.用户在表单中输入的数据实时绑定在person对象的同名属性中;
    • 2.在person对象中进行属性的修改会实时反映在表单中;
  • 获取form的DOM节点,并且设置默认值,该默认值在Vue中就是data对象中的数据;

     

  • 实现用户输入数据与person对象内同名属性的同步修改
    • 一、用Object.defineProperty为person对象设定name和age两个属性,并且他们的get获取的是_data里的数据

    • 二、监听form表单中的input事件,并且将获取的目标DOM节点的value值赋值给person对象中的响应属性即可完成用户输入与对象值间的绑定

       

       

      效果图:

       

  • 实现person对象同名属性的修改同步用户表单框中的输入值

     

     

     

    效果图:修改直接修改person对象中的name和age属性的值,可以同步显示在输入框中

     

  • 这时候其实已经完成了数据的双向绑定,再做一些小优化

     

缺点

本身form节点中只有name和age两个输入框对应person中的属性,如果这时候我在form节点中新添加一个输入框进去,这个新添加的input输入的值是没有双向绑定效果的;
PS:在Vue中,created函数后新添加的属性不会进行监听,因为这时候的数据已经初始化完毕,当然Vue本身也提供了一个Vue.set(object, key, value)api,使其可以在created后对data对象进行属性的添加;

Vue.js 细节

Vue.js 是采用 Object.defineProperty 的 getter 和 setter,并结合观察者模式来实现数据绑定的。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

  

Observer 数据监听器,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者,内部采用Object.defineProperty的getter和setter来实现。

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

Watcher 订阅者, 作为连接 Observer 和 Compile 的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数。

Dep 消息订阅器,内部维护了一个数组,用来收集订阅者(Watcher),数据变动触发notify 函数,再调用订阅者的 update 方法。

从图中可以看出,当执行 new Vue() 时,Vue 就进入了初始化阶段,一方面Vue 会遍历 data 选项中的属性,并用 Object.defineProperty 将它们转为 getter/setter,实现数据变化监听功能;另一方面,Vue 的指令编译器Compile 对元素节点的指令进行扫描和解析,初始化视图,并订阅Watcher 来更新视图, 此时Wather 会将自己添加到消息订阅器中(Dep),初始化完毕。

当数据发生变化时,Observer 中的 setter 方法被触发,setter 会立即调用Dep.notify(),Dep 开始遍历所有的订阅者,并调用订阅者的 update 方法,订阅者收到通知后对视图进行相应的更新。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值