资讯专栏INFORMATION COLUMN

前端 MVVM 原理

leiyi / 2606人阅读

摘要:原来是在改变数据时,还要手动。现在只需要直接改变数据,会自动,更新元素。参考资料现代前端技术解析,张成文,年月第版,和的图示,阮一峰,年月日,

author: 陈家宾
email: 617822642@qq.com
date: 2018/3/1
MVVM 背景

都说懒惰使人进步,MVVM 的进化史,正印证了这句话,是一步步让开发人员更懒惰更简单的历史:

直接 DOM 操作 -> MVC -> MVP -> MVVM

最开始的前端交互,是很直接的 DOM 操作,最出名的这类库当数 jQuery 了,封装了 DOM API,让一切 DOM 操作都变得简单。

但当页面数据和交互多的时候,散乱的代码将使项目变得难以维护,让人发狂。所以才有了 MV* 模式的发展。

MV* 模式
MVC & MVP & MVVM 三者对比伪代码:点我
MVC

Model:数据模型 & 手动渲染模板

View:模板

Controller:修改数据

MVP

Model:数据模型

View:模板

Presenter:修改数据 & 手动渲染模板

MVP 是 MVC 模式的一种改造(这里不说改进,是因为两者其实很相似,没有本质上的变化),将 手动渲染 步骤** 从 Model 移到了 Presenter,让 View 和 Model 更独立更存粹了,但从另一个角度来说,也加大了 Presenter 的工作。

MVVM

Model:数据模型

View:带特殊属性的 html 模板

ViewModel:依靠 Directive,修改数据 & 自动渲染

MVVM 模式依靠 Directive,实现了 模板自动渲染,极大地解放了开发者的双手,此时开发者只需关注 View 和 Model,效率和可维护性方面达到了飞跃式的进步。

下面将着重介绍下神奇的 Directive。

数据变更检测方案(Directive) (一)手动触发绑定

在页面需要改变时,手动触发检测,改变 model 数据,并扫描元素,对有特殊标记的元素进行修改

let data = {
      value: "hello"
};

let directive = {
    html: function (html) {
        this.innerHTML = html;
    },
    value: function (html) {
        this.setAttribute("value", value);
    }
};

ViewModelSet("value", "hello world");

function ViewModelSet(key, value) {
    data[key] = value;
    scan(); 
}

function scan() {
    for (let elem of elems) {
        elem.directive = [];
        for (let attr of elem.attributes) {
            if (attr.nodeName.indexOf("v-") >= 0) {
                directive[attr.nodeName.slice(2)].call(elem, data[attr.nodeValue]);
            }
        }
    }
}
(二)脏检测机制

针对手动绑定进行优化,只对修改到的数据进行更新元素

function scan(elems, val) {
    let list = document.querySelectorAll(`[v-bind=${val}]`); // 只扫描修改到的数据涉及的元素
    for (let elem of elems) {
        for (let attr of elem.attributes) {
            let dataKey = elem.getAttribute("v-bind");
            if (elem.directive[attr.nodeValue] !== data[dataKey]) { // 当元素值有变时,更新元素
                directive[attr.nodeValue].call(elem, data[dataKey]); 
                elem.directive[attr.nodeValue] = data[dataKey]; // 保存元素当前值
            }
        }
    }
}
(三)前端数据对象劫持(Hijacking)

在上面的基础更进一步,使用 Object.defineProperty 对数据进行 get & set 监听,当数据有变时,自动执行 scan 扫描并更新元素。

原来是在改变数据时,还要手动 scan。现在只需要直接改变数据,会自动 scan,更新元素。

defineGetAndSet(data, "value");

data.value = "hello world";

function defineGetAndSet(obj, propName) {
    Object.efineProperty(obj, propName, {
        get: function () {
            return this.bVal;
        },
        set: function (newVal) {
            this.bVal = newVal;
            scan();
        },
        enumerable: true,
        configurable: true
    });
}
(四)ECMAScript 6 Proxy

与方法三类似,换了种写法,这里应用了 ES6 里的 Proxy

let data = new Proxy({
    get: function (obj, key) {
        return obj[key];
    },
    set: function (obj, key, val) {
        obj[key] = val;
        scan();
        return obj[key];
    }
});

以上。

参考资料

《现代前端 技术解析》,张成文,2017 年 4 月第 1 版d

《MVC,MVP 和 MVVM 的图示》,阮一峰,2015年2月 1日,http://www.ruanyifeng.com/blo...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93034.html

相关文章

  • MVVM框架理解及其原理实现

    摘要:小白一枚,一直使用的是,想要多了解一些其它的框架,正好最近越来越火热,上的数已经超过了。框架理解说起这个模型,就不得不说框架。函数表示创建一个文本节点,函数表示创建一个数组。 小白一枚,一直使用的是React,想要多了解一些其它的框架,正好最近Vue越来越火热,Github上的Star数已经超过了React。而其背后蕴含的MVVM框架思想也一直跟React的组件化开发思想并驾齐驱,在这...

    DevWiki 评论0 收藏0
  • 我的前端面试

    摘要:前言这次找工作也面了好几家公司,也通过了好几家公司的面试,毕竟之前也准备了一段时间,所以面试的时候心里也不是很虚。的代码分割怎么实现的说说刚才提到的和的区别前端缓存怎么实现扯扯强缓存和协商缓存,重点问了如何实现缓存二面就聊了项目。。。 前言 这次找工作也面了好几家公司,也通过了好几家公司的面试,毕竟之前也准备了一段时间,所以面试的时候心里也不是很虚。 这里记录一下面试过程中被问到的问题...

    meteor199 评论0 收藏0
  • 前端的发展历程

    摘要:前端的发展历程什么是前端前端针对浏览器的开发,代码在浏览器运行后端针对服务器的开发,代码在服务器运行前端三剑客超文本标记语言是构成世界的基石。 前端的发展历程 什么是前端 前端:针对浏览器的开发,代码在浏览器运行 后端:针对服务器的开发,代码在服务器运行 前端三剑客 HTML CSS JavaScript HTML HTML(超文本标记语言——HyperText Markup ...

    刘明 评论0 收藏0
  • 利用 JavaScript 数据绑定实现一个简单的 MVVM

    摘要:和刷新函数是一对多的关系,即一个可以有任意多个处理它的回调函数刷新函数,比如和两个指令共用一个数据模型字段。添加数据订阅实现方式为建立缓存回调函数的数组缓存回调函数当数据模型的字段发生改变时,就会触发缓存数组中订阅了的所有回调。 MVVM 是 Web 前端一种非常流行的开发模式,利用 MVVM 可以使我们的代码更专注于处理业务逻辑而不是去关心 DOM 操作。目前著名的 MVVM 框架有...

    hzx 评论0 收藏0
  • 状态决定视图——基于状态的前端开发思考

    摘要:前端与状态现在的前端开发中,对于状态的管理是重中之重。有限状态机那么如何更好的管理前端软件的复杂度的状态机思想给出了自己的答案。有限状态机并不是一个复杂的概念简单说,它有三个特征状态总数是有限的。 前提 在现在的前端社区,关于MVVM、Model driven view 之类的概念,已经算是非常普及了。React/Vue 这类框架可以算是代表。而自己虽然有 React/Vue 的使用经...

    miya 评论0 收藏0

发表评论

0条评论

leiyi

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<