Understanding of MVVM pattern

MVVM The full name Model-View-ViewModel is based on the improvement of MVC the MVP architecture pattern, which MVVM is the abstraction of the state and behavior in the pattern, separating the view MVC and business logic, and more clearly distinguishing the development of the user interface from the development of business logic and behavior in the application. .View UI UI

Understanding of MVVM pattern

Understanding of MVVM pattern

MVVM The full name Model-View-ViewModel is based on the improvement of MVC the MVP architecture pattern, which MVVM is the abstraction of the state and behavior in the pattern, separating the view MVC and business logic, and more clearly distinguishing the development of the user interface from the development of business logic and behavior in the application. .View UI UI

describe

MVVM Patterns simplify the interface and business dependencies, helping to separate the development of the graphical user interface from the development of business logic or data models. As a binder in the link, the view layer and MVVM the data layer are linked. When updating, the data is updated through the binder. When triggering an instruction, it will pass a message to it , like a black box. During the development process Only need to focus on the presented view layer and the data layer of the abstract model , and don't need to pay too much attention to how the data and messages are passed. ViewModel UI Model Model ViewModel View View ViewModel ModelViewModel UI Model ViewModel

composition

Model

  • The result of object-oriented abstraction of things is a domain model that represents the real state content.
  • It can also be Model referred to as the data layer, which as a data center only focuses on the data itself, not on any behavior.

View

  • View is the structure, layout, and appearance that the user sees on the screen, the view UI.
  • When Model an update is made, ViewModel it will be updated to via data binding View.

ViewModel

  • ViewModel is an abstraction of views exposing public properties and commands.
  • ViewModel The binders in the communicate between the view and the data binder.
  • When Model updating, ViewModel the data is updated to through the binder, View and when the View instruction is triggered, it will be ViewModel passed the message to Model.

advantage

  • Low coupling: Views View can be independent of Model changes and modifications, one ViewModel can be bound to a different one View, can be unchanged when it changes, and can be unchanged when View it changes .ModelModelView
  • Reusability: You can put some view logic in one ViewModel, allowing many to View reuse this view logic.
  • Independent development: Developers can focus on the development of business logic and data Model, and designers can focus on page design.
  • Testable: Interfaces have always been difficult to test, and testing behavior can be done through ViewModel.

insufficient

  • For overly large projects, data binding will cost more memory.
  • Data binding makes it Bug difficult to debug. When the interface is abnormal, there may be View a problem with the code, or there may be Model a problem with the code. Data binding makes it Bug possible to quickly transfer information from one location to another location. It is necessary to locate the original problem. Places just don't get easier.

example

Vue The following is a simple data binding example of the reference implementation.

< ! DOCTYPE html > 
< html > 
< head > 
    < title > Data Binding < / title > 
< / head > 
< body > 
    < div id = "app" > 
        < div > { { msg } } < / div > 
        < div > { { date } } < / div > 
        <button onclick = "update()" > update < / button > 
    < / div >  
< / body > 
< script type = "text/javascript" >

///////////////////////////////////////////// /////////////////////////// 
    var  Mvvm  =  function ( config )  { 
        this . $el = config . el ; 
        this . __root = document . querySelector ( this . $el ) ; 
        this . __originHTML =  this . __root . innerHTML ;

        function  __dep ( ) { 
            this . subscribers =  [ ] ; 
            this . addSub  =  function ( watcher ) { 
                if ( __dep . target &&  ! this . subscribers . includes ( __dep . target )  )  this . subscribers . push ( watcher ) ; 
            } 
            this .notifyAll _ =  function ( ) { 
                this . subscribers . forEach (  watcher  => watcher . update ( ) ) ; 
            } 
        }


        function  __observe ( obj ) { 
            for ( let item in obj ) { 
                let dep =  new  __dep ( ) ; 
                let value = obj [ item ] ; 
                if  ( Object . prototype . toString . call ( value )  ===  "[object Object] " )  __observe ( value ) ; 
                Object.defineProperty ( obj , item , { 
                    configurable : true , 
                    enumerable : true , get : function reactiveGetter ( ) { if ( __dep . target ) dep . addSub ( __dep . target ) ; return value ; } , set : function reactiveSetter ( newVal _   
                       
                        
                        
                    
                      )  { 
                        if  ( value === newVal )  return value ; 
                        value = newVal ; 
                        dep . notifyAll ( ) ; 
                    } 
                } ) ; 
            } 
            return obj ; 
        }

        this . $ data =  __observe ( config.data ) ; _

        function  __proxy  ( target )  { 
            for ( let item in target ) { 
                Object . defineProperty ( this , item ,  { 
                    configurable :  true , 
                    enumerable :  true , 
                    get :  function  proxyGetter ( )  { 
                        return  this . $data [ item ] ; 
                    } ,
                    set :  function  proxySetter ( newVal )  { 
                        this . $data [ item ]  = newVal ; 
                    } 
                } ) ; 
            } 
        }

        __proxy.call ( this , config.data ) ; _ _ _ _

        function  __watcher ( fn ) { 
            this . update  =  function ( ) { 
                fn ( ) ; 
            }

            this . activeRun  =  function ( ) { 
                __dep . target =  this ; 
                fn ( ) ; 
                __dep . target =  null ; 
            } 
            this . activeRun ( ) ; 
        }

        new  __watcher ( ( )  =>  { 
            console . log ( this . msg ,  this . date ) ; 
        } )

        new  __watcher ( ( )  =>  { 
            var html =  String ( this . __originHTML || '' ) . replace ( / " / g , '\\"' ) . replace ( / \s+|\r|\t|\n / g ,  ' ' ) 
            .replace ( / \{\{(.)*?\}\ } / g , function ( value ) { return   value  
                .replace ( "{{" , ' "+(' ) .replace ( "}}" , ' ) +"' ) ; } ) 
            html = ` var targetHTML = " ${ html } ";return targetHTML; ` ; var parsedHTML = new Function ( ... Object . keys ( this . $data ) , html ) ( ... Object . values ​​(
             
              this . $data ) ) ; 
            this . __root . innerHTML = parsedHTML ; 
        } )

    }

///////////////////////////////////////////// ///////////////////////////

    var vm =  new  Mvvm ( { 
        el :  "#app" , 
        data :  { 
            msg :  "1" , 
            date :  new  Date ( ) , 
            obj :  { 
                a :  1 , 
                b :  11 
            } 
        } 
    } )

    function  update ( ) { 
        vm . msg =  "updated" ; 
    }

///////////////////////////////////////////// /////////////////////////// 
< / script > 
< / html >

What's Your Reaction?

like
0
dislike
0
love
0
funny
0
angry
0
sad
0
wow
0