MVVM 框架

问题:vue

一、MVVM 的定义程序员

 

  M (Model): 数据来源,服务器上业务逻辑操做数据库

  V (View): 界面,页面设计模式

  VM (ViewModel): view 和 model 的核心枢纽,如 vue.js数组

  Model 和 ViewModel 的双向关系:服务器

  一、 Model 经过 Ajax (服务器) 通讯,发送数据给 ViewModel网络

  二、 ViewModel 经过 Ajax (服务器) 通讯,回传数据给 Model框架

  View  和 ViewModel 的双向关系函数

  一、 ViewModel 的数据改变,会映射到 View(便可以即时改变 View 显示的内容)设计

  二、View 的内容改变,也会同时改变 ViewModel 对应的数据

 

 

二、对比MVC 和 MVVM

  认识MVC: Controller 负责 将 Model 的数据在 View 中显示出来(即 Controller 负责将 Model 的数据赋值给View),好比在controller中写document.getElementById("box").innerHTML = data[”title”],只是尚未刻意建一个Model类出来而已。

    M (Model): 模型,应用程序处理数据的部分,一般指从数据库读取数据

    V  (View): 视图,界面, 应用工程处理界面显示的部分,一般根据模型数据建立

    C (Controller): 控制器, 应用程序控制用户交互的部分,一般负责从View读取数据,控制用户输入,向 Model 发送数据

  斯坦福大学公开课上的这幅图来讲明,这能够说是最经典和最规范的MVC标准

    

    从上图能够看出: C能够直接引用 V 和 M, V 和 M 不能(不该该)直接引用 C

    View 和 Controller 之间的交互:

      View 把事件传递给 Controller,Controller 至关于靶子,View 和 Controller 有两种交互方式:一种是: target->action,另外一种是:协议->委托,委托有两种方式 代理和数据源:代理是 should,will,did 等等的委托,数据源是 data,count 等等的委托

    Model 和 Controller 之间的交互:

      Model是数据管理者,可理解为它直接和数据库打交道,Model 和 View 应该是一种同步关系,即无论任什么时候候只要 Model 的数据发生改变,View 显示的内容也应该发生改变。咱们可关注 Model 的值发生改变而不用关心 Model 的网络请求是否结束了,Controller 根本不关心Model从哪里拿数据,Controller 的责任是把Model 最新的值赋值给View,Controller 关注的是Model 的值是否发生改变

 

  MVVM 的诞生:

    须要数据有M, 须要界面有V,把M 的数据给V显示,因此有 C,可是咱们忽略了一个重要的操做:数据解析,在MVC 时代手机API数据比较简单,极可能一步就解决,那时把数据解析交给 Controller完成,可是如今手机API 数据愈来愈复杂,数据解析就没有那么简单了,若是继续按照MVC 的设计思路,将数据解析放到C完成,C 将会变得至关臃肿。Controller 设计出来并非处理数据解析的,而是:一、管理本身的生命周期, 二、处理 Controllder 之间的跳转, 三、 实现 Controller 容器。在MVC 没有谁是负责处理数据解析的,那么将由谁负责处理数据解析呢?没有就建立一个新的类出来,开发者们专门为数据解析建立出一个新的类:ViewModel,因而 MVVM就诞生了

 

  MVVM 的实现:

    在MVVM Controller 的存在感被彻底下降了,VM 的出现是Controller 存在感下降的缘由。VM 先拿到原始数据,通过数据解析,把结果给Controller,由于 Controller只须要 数据解析的结果而不关心过程,因此至关于 VM 把如何解析Model 的数据封装起来了,C 根本不须要知道这个M 的存在,前提是有VM, 一旦在实现 Controller中遇到任何与Model(数据)有关的问题就找 VM

三、 数据双向绑定的原理

  双向绑定是什么意思?

  

  

  双向是指ViewModel中的data部分和View之间的双向关系。
  正向:数据驱动页面
  反向:页面更新数据

  绑定是指自动化处理,data改变了view随之改变,反之也是。
  不用像传统方式那样,经过onChange事件获取用户输入,而后再经过改变innerHtml修改显示。

 

  双向绑定的原理是什么?能够写出来吗?

  双向绑定都是依赖ES5中一个重要的API,Object.defineProperty。

  正向:

  Object.defineProperty的做用:

    监听到 data的变化,监听到变化后会有个回调函数,在定义的时候直接写回调函数,在Object.defineProperty回调函数写明 view 和 data 的关联关系,后续中data有变化就会自动根据你写的关联处理修改View的显示内容。直接操做修改data是由于 Object.defineProperty 有 set 属性

  反向:

  在view中输入内容时,经过 input 事件(好比 onchange),修改 data。只不过这件事不须要咱们程序员本身去写了,有些框架背后在作这件事,好比,在Vue框架中,可使用V-Model方便的关联view和data。

 

  Object.defineProperty()

  定义:

  Object.defineProperty() 方法是在一个对象新定义一个属性,或者修改一个对象的现有属性,返回修改后的这个对象(换句话就是 修改一个对象返回一个修改后的对象)

  语法:

  Object.defineProperty(obj, prop, descriptor)

  参数:
  obj:要在其上定义属性的对象。
  prop:要定义或修改的属性的名称。
  descriptor:将被定义或修改的属性描述符。

  返回值
  被传递给函数的对象。

  具体解释可看:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

 

  Object.defineProperty 与 Reflect.defineProperty 的区别:

  Object.defineProperty是 ES5 的用法,返回的是一个对象

  Reflect.defineProperty是ES6 的用法,返回的是一个布尔值 

 

Object.defineProperty缺点:

  • 深度监听,须要递归到底,一次性计算量大
  • 没法监听新增/删除属性(因此须要 vue.set vue.delete 实现新增/删除属性)
  • 没法监听原生数组,须要特殊处理

 

 

四、 设计模式 (观察者模式)

  

    1. 监听者 (Observer): 有一个监听者(Observer),监听 data发生的变化, (经过Object.defineProperty 的get 属性从新遍历,修改 get 和 set 操做,还会有一个递归的操做,若是操做的是一个子对象,会对这个子对象从新进行递归遍历一遍保证全部的key值都是有 observer 对象的。)

    2. 观察者列表 (Dep): 数据的变化会触发 Object.defineProperty 对象的set 属性,set 会执行对观察者列表的触发,通知观察者列表(Dep)

    3. 列表会有一个更新函数,通知了它们,它们会自动调用 updated 更新函数,也就是 Dep 调用了 回调,这个 回调是 观察者 (watcher)给的

    4. 观察者(watcher): watcher 拿到更新后的数据就能够更新到 view了

    5. 观察者列表的updated 是怎么传进去的,是经过 watcher 的订阅,watcher 往观察者列表添加新的内容(监听完后会有一步实例化 watcher 对象,想对A 操做,observer 完后会手动调用一下watcher,实例化watcher,watcher 会调用 get,检测watcher全局变量是否有值,有值的话会调用 deep.target,把内容往 Dep添加)

相关文章
相关标签/搜索