Vue   发布时间:2022-04-21  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了MVVM模式的理解大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

MVVM模式的理解

MVVM全称Model-View-viewmodel是基于MVCMVP体系结构模式的改进,MVVM就是MVC模式中的View的状态和行为抽象化,将视图UI和业务逻辑分开,更清楚地将用户界面UI的开发与应用程序中业务逻辑和行为的开发区分开来。

描述

MVVM模式简化了界面与业务的依赖,有助于将图形用户界面的开发与业务逻辑或数据模型的开发分离开来。在MVVM中的viewmodel作为绑定器将视图层UI与数据层Model链接起来,在Model更新时,viewmodel通过绑定器将数据更新到View,在View触发指令时,会通过viewmodel传递消息到Modelviewmodel像是一个黑盒,在开发过程中只需要关注于呈现UI的视图层以及抽象模型的数据层Model,而不需要过多关注viewmodel是如何传递的数据以及消息。

组成

Model

  • 以面向对象来对对事物进行抽象的结果,是代表真实状态内容的领域模型。
  • 也可以将Model称为数据层,其作为数据中心仅关注数据本身,不关注任何行为。

View

  • View用户在屏幕上看到的结构、布局和外观,即视图UI
  • Model进行更新的时候,viewmodel会通过数据绑定更新到View

viewmodel

  • viewmodel是暴露公共属性和命令的视图的抽象。
  • viewmodel中的绑定器在视图和数据绑定器之间进行通信。
  • Model更新时,viewmodel通过绑定器将数据更新到View,在View触发指令时,会通过viewmodel传递消息到Model

优点

  • 低耦合: 视图View可以独立于Model变化和修改一个viewmodel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 可重用性: 可以把一些视图逻辑放在一个viewmodel里面,让很多View重用这段视图逻辑。
  • 独立开发: 开发人员可以专注于业务逻辑和数据的开发Model,设计人员可以专注于页面设计。
  • 可测试: 界面素来是比较难于测试的,测试行为可以通过viewmodel来进行。

不足

  • 对于过大的项目,数据绑定需要花费更多的内存。
  • 数据绑定使得Bug较难被调试,当界面异常,可能是View代码有问题,也可能是Model 代码有问题,数据绑定使得一个位置的Bug可能被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。

实例

下面是参照Vue实现的简单的数据绑定实例。

<!DOCTYPE html>
<html>
<head>
    <title>数据绑定</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,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>

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://zhuanlan.zhihu.com/p/38296857
https://baike.baidu.com/item/MVVM/96310
https://www.liaoxuefeng.com/wiki/1022910821149312/1108898947791072

大佬总结

以上是大佬教程为你收集整理的MVVM模式的理解全部内容,希望文章能够帮你解决MVVM模式的理解所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: