zoukankan      html  css  js  c++  java
  • MVC与MVVM区别?

      在MVC里,View是可以直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。 MVC模型关注的是Model的不变,所以,在MVC模型里,Model不依赖于View,但是 View是依赖于Model的。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的。

      MVVM在概念上是真正将页面与数据逻辑分离的模式,它把数据绑定工作放到一个JS里去实现,而这个JS文件的主要功能是完成数据的绑定,即把model绑定到UI的元素上。

      有人做过测试:使用Angular(MVVM)代替Backbone(MVC)来开发,代码可以减少一半。

      此外,MVVM另一个重要特性,双向绑定。它更方便你同时维护页面上都依赖于某个字段的N个区域,而不用手动更新它们。

    前端MVVM框架设计及实现(一)

      最近抽出点时间想弄个dom模块化的模板引擎,不过现在这种都是MVVM自带的,索性就想自己造轮子写一个简单的MVVM框架了

    借鉴的自然还是从正美的avalon开始了,我记得还是去年6月写过一个系列的avalon源码分析的,不过那时候0.7版本,不够健全,现在已经好太多了

      框架是面向一个领域,提供一套解决方案,那么我们用前端的MVVM能为我们带来什么便利?

    • 关注点分离
    • 操作数据即操作DOM
    • 动态模板

      关注点分离是MVVM与身俱来的,操作数据即操作DOM,是VM中的访问器带来的,动态模板是流程绑定实现的。

    关于MV*的讨论太多了,这里不在讨论,我们重点就是分析如何实现前端MVMM框架

    Avalon 地址 https://github.com/RubyLouvre/avalon


      学会MVVM需要先会哪些东西?

    1. javascript语言基础(作用域,原型链,闭包等等)

    2. 简单设计模式,基本的数据结构

    3. 阅读或者写过jQuery源码

      为什么要这样说呢,因为avalon就是这些东东的综合体!


      我是以avalon为蓝本,按照作者是思路模仿实现的,当然avalon的代码有4000多行,新手如果去学习的话估计无从下手,也力不从心

    为什么呢?简单的说实现的手段有点另类,写的代码有点狂野(请原谅我不知道如何形容),不过用户体验倒是不错!

    简单的看下代码结构

    <div ms-controller="box">
         <div style=" background: #a9ea00;" ms-css-width="w" ms-click="click"></div>
         <p>{{ w }}p>
     </div>
     <script>
         avalon.define("box", function(vm) {
             vm.w = 100;
             vm.click = function() {
                 vm.w = parseFloat(vm.w) + 10;
             }
         })
     </script>

    针对这个代码结构,我们要明白:

    1:为什么要自定义大量标记(声明式绑定)

    这就是MVVM 最原始的意义,数据逻辑展现分离。表现就是 数据 js逻辑代码 htmlcss展现

    所以再HTML里加结构是自然而然的事情,如果html都用js生成,那就跟mvvm搭不上边

    2:avalon.define里面为什么不需要操作dom?

    在MVVM中,数据是核心,由于VM与V之间的双向绑定,操作了VM中的数据(当然只能是监控属性),就会同步到DOM,我们透过DOM事件监控用户对DOM的改动,也会同步到VM。


    本章我们就实现第一步:搭建基本的分层结构,实现双向通知机制

    第一版实现:300行代码,请对照分析看源码 https://github.com/JsAaron/aaMVVM

    针对上面2个问题,我们看看如何才能做到操作数据即操作dom呢?

    简单的说一下实现是思路:大家可以down下git的aaMVVM对照下,比原版的4000行代码友爱多了!

    我们知道在MVVM中,M只是一个过客,它与其他表示业务状态的东西融入VM(ViewModel)中。ViewModel是一个状态的集合,当然还拖家带口监控着大量的回调

    所以ViewModel就承载的几乎所有的功能,在avalon中ViewModel就包含所有的数据与方法的定义,沟通着V与M,起到承上启下的作用~


    视图模型如何与数据跟视图关联起来?

    通过avalon.define定义的vm中的属性与方法都与对应的html结构中的标记有映射关系,所以改变vm中的数据与之关联的dom就会自动刷新

    分析下

    vm.w = 100

    当模型的数据改变为100时,对应的视图中div的宽度为100, 文本<p>100</p>  ,可见修改一个数据在同一个控制器内与之关联的2个映射动作都将会修改

    一个是css操作,一个是text赋值

    从这个操作我们可以大胆推测下vm.v中应该有一个列表,记录了当前控制器下对应的映射操作(多个)

    为了实现set与get方法,avalon也类似emberjs,采用了Object.defineProperty

    我用最简单的代码模拟下实现

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>测试VM</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
    </head>
    <body>
        <div id='box' ao-controller="box">
            <div id='aa-attr' style="background: #a9ea00;100px;height:100px;" ao-css-width="w" ao-click='click' ></div>
            <p id='aa-text'>{{ w }}</p>
        </div> 
    
    </body>
    </html>

    也就是说

    vm.w = 100  即要修改style也要修改p,就是一对多的关联方式

    所以在avalon中针对每一个监控属性,都会生成set与get的访问控制器,那么在每一个监控属性的访问控制器里面都会有一个

    accessor[subscribers] = [] //订阅者数组,这样的东东来存放与之相关的依赖

    image

    当我们触发  vm.w = 100时,就会触发w:set方法,取出accessor[subscribers]中的依赖,从而各执执行,这样就实现了依赖执行了

    对应的方法:自动更新自身的依赖

     //通知依赖于这个访问器的订阅者更新自身
    function notifySubscribers(accessor) {
        var list = accessor[subscribers]
        if (list && list.length) {
            var args = [].slice.call(arguments, 1)
            for (var i = list.length, fn; fn = list[--i];) {
                var el = fn.element
                fn.handler(fn.evaluator.apply(0, fn.args || []), el, fn)
            }
        }
    }

    上面只是简单的思路,真正实现的时候真要做到大而全的框架,考虑的问题可不是那么简单的事

    1 框架是怎么解释声明式绑定的语法

    2 如何把解析后的语法生成对应的处理句柄

    3 用户的定义如何生成vm模型

    4 如何收集这些依赖

    5 如何自动更新依赖映射

    GitHub上会同步更新最新的实现,。。。敬请关注~

    Fork https://github.com/JsAaron/aaMVVM

  • 相关阅读:
    读spring Micro-Service tats收获
    读spring Micro-Service tats收获
    读spring Micro-Service tats收获
    读Software Entity Architektur收获
    读Software Entity Architektur收获
    读Software Entity Architektur收获
    mvc案例
    11.16
    11.15
    11.13
  • 原文地址:https://www.cnblogs.com/chqq2018/p/10443196.html
Copyright © 2011-2022 走看看