引言

现在的前端真可谓是百花齐放,百家争鸣,各种框架层出不穷,但是主要目前用的最多的还是要数VueReact、以及Angular,这三种,当然不乏近期新出的一些其他框架,但是她们都有一个显著的特点,那就是使用了MVVM的架构。

首先我们要搞清楚什么是MVVM

MVVM就是Model-View-ViewModel的缩写,MVVM最早由微软提出来,它借鉴了桌面应用程序的MVC思想,在前端页面中,把Model用纯JavaScript对象表示,View负责显示,两者做到了最大限度的分离。把ModelView关联起来的就是ViewModelViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model

改变JavaScript对象的状态,会导致DOM结构作出对应的变化!这让我们的关注点从如何操作DOM变成了如何更新JavaScript对象的状态,而操作JavaScript对象比DOM简单多了。

这就是MVVM的设计思想:关注Model的变化,让MVVM框架去自动更新DOM的状态,从而把开发者从操作DOM的繁琐步骤中解脱出来!

接下来我会带着你们如何去实现一个简易的MVVM架构。

一、构建MVVM构造函数

创建一个MVVM构造函数,用于接收参数,如:datamethodscomputed等:

function MVVM(options) { this.$options = options; let data = this._data = this.$options.data; observe(data); for (let key in data) { Object.defineProperty(this, key, { enumerable: true, get() { return this._data[key]; }, set(newVal) { this._data[key] = newVal; } }); }; initComputed.call(this); new Compile(options.el, this); options.mounted.call(this);
}
复制代码

二、构建Observe构造函数

创建一个Observe构造函数,用于监听数据变化:

function Observe(data) { let dep = new Dep(); for (let key in data) { let val = data[key]; observe(val); Object.defineProperty(data, key, { enumerable: true, get() { Dep.target && dep.addSub(Dep.target); return val; }, set(newVal) { if (val === newVal) { return; } val = newVal; observe(newVal); dep.notify(); } }); };
};
复制代码

三、构建Compile构造函数

创建一个Compile构造函数,用于解析模板指令:

function Compile(el, vm) { vm.$el = document.querySelector(el); let fragment = document.createDocumentFragment(); while (child = vm.$el.firstChild) { fragment.appendChild(child); } replace(fragment);function replace(frag) {Array.from(frag.childNodes).forEach(node => { let txt = node.textContent; let reg = /\{\{(.*?)\}\}/g; if (node.nodeType === 3 && reg.test(txt)) { let arr = RegExp.$1.split('.'); let val = vm; arr.forEach(key => { val = val[key]; }); node.textContent = txt.replace(reg, val).trim(); new Watcher(vm, RegExp.$1, newVal => { node.textContent = txt.replace(reg, newVal).trim(); }); }if (node.nodeType === 1) { let nodeAttr = node.attributes; Array.from(nodeAttr).forEach(attr => { let name = attr.name; let exp = attr.value; if (name.includes('v-')) { node.value = vm[exp]; } new Watcher(vm, exp, newVal => { node.value = newVal; }); node.addEventListener('input', e => { let newVal = e.target.value; vm[exp] = newVal; }); }); };if (node.childNodes && node.childNodes.length) { replace(node); } }); }vm.$el.appendChild(fragment);
}
复制代码

四、构建Watcher构造函数

创建一个Watcher构造函数,用于更新视图:

function Watcher(vm, exp, fn) { this.fn = fn; this.vm = vm; this.exp = exp; Dep.target = this; let arr = exp.split('.'); let val = vm; arr.forEach(key => { val = val[key]; }); Dep.target = null;
} Watcher.prototype.update = function() { let arr = this.exp.split('.'); let val = this.vm; arr.forEach(key => { val = val[key]; }); this.fn(val);
}
复制代码

五、构建Dep构造函数

创建一个Dep构造函数,用于管理Watcher:

function Dep() { this.subs = [];
} Dep.prototype.addSub = function(sub) { this.subs.push(sub);
} Dep.prototype.notify = function() { this.subs.forEach(sub => { sub.update(); });
}
复制代码

六、构建initComputed构造函数

创建一个initComputed构造函数,用于初始化计算属性:

function initComputed() { let vm = this; let computed = this.$options.computed; Object.keys(computed).forEach(key => { Object.defineProperty(vm, key, { get: typeof computed[key] === 'function' ? computed[key] : computed[key].get, set() {} }); });
}
复制代码

总结:

至此我们就完成了一个简易的MVVM框架,虽然简易,但是基本的核心思想差不多都已经表达出来了,最后还是希望大家不要丢在收藏文件夹里吃灰,还是要多多动手练习一下,所谓眼过千遍,不如手过一遍。

手把手教你实现MVVM架构相关推荐

  1. Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影系统

    作者:JackTian 微信公众号:杰哥的IT之旅(ID:Jake_Internet) LAMP 系列导读 01. LAMP 系列教程(一)| 详解 Linux 环境下部署 HTTPD 服务 02. ...

  2. 手机端创新体验——手把手教你搭建VRAR架构

    声明:本文阿里巴巴技术论坛整理文章,首发于CSDN,未经许可,禁止任何形式的转载. 作者:袁岳峰,阿里移动平台虚拟&互动实验室负责人,GM Lab技术负责人. 责编:钱曙光,关注架构和算法领域 ...

  3. 阿里云专家手把手教你重塑 IT 架构!

    进入21世纪以来,我们见证了企业分布式应用架构从SOA(Service-Oriented Architecture)到微服务架构,再到云原生应用架构的演化. 为了说明企业架构演化背后的思考,我们先谈一 ...

  4. 大神手把手教你设计秒杀架构模型

    中生代技术 链接技术大咖,分享技术干货 全文:4000字 作者:Yrion 原文首发:https://www.cnblogs.com/wyq178/p/11261711.html 前言:秒杀系统相信很 ...

  5. 资深架构师手把手教你性能优化

    图片来源:pexels.com 孔庆龙,一线架构师,具有多年的金融架构经验,具备 SOA 服务化.服务治理.系统优化.分布式系统项目经验.目前关注于互联网金融技术架构设计.分布式架构.微服务架构.De ...

  6. 百度架构师手把手教深度学习之心得

    <<百度架构师手把手教深度学习>>心得 课程内容 作业打磨 感言 祝愿 课程链接 经过紧张有序的三个星期的学习,终于完成了<百度架构师手把手教深度学习>>! ...

  7. 手把手教你架构3D引擎高级篇概述

    前几年写过一本书<手把手教你架构3D游戏引擎>电子工业出版社,主要内容讲的是固定流水线编程,目的是让读者理解第一代引擎是如何实现的,从本篇博客开始,给读者介绍关于使用可编程流水线自己搭建3 ...

  8. 云架构师进阶【SAP迁移方案设计】手把手教您玩转SAP上云

    一,项目背景介绍 今天又接到了北京某制造企业SAP迁移的场景,先简单说明一下,好好的SAP在运行着为什么要做迁移这类大动作呢?众所周知SAP的ERP是企业的绝对核心系统,尤其对于制造业更是核心的系统, ...

  9. [原创]手把手教你写网络爬虫(2):迷你爬虫架构

    手把手教你写网络爬虫(2) 作者:拓海 (https://github.com/tuohai666) 摘要:从零开始写爬虫,初学者的速成指南! 封面: 介绍 大家好!回顾上一期,我们在介绍了爬虫的基本 ...

最新文章

  1. msteel能计算钢结构楼梯吗_坚持爬楼梯能减肥吗 怎么爬楼梯可以减肥
  2. 双系统XP和ubuntu,升级ubuntu出现no such device grub rescue
  3. 项目: 用easyx实现消砖块
  4. php抓取页面400错误
  5. Python中各进制间的转换
  6. 数组和lookup函数
  7. 训练日志 2019.7.25
  8. 消除ie上的:为了有利于保护安全性,IE已限制此网页运行可以访问计算机的脚本或 ActiveX 控件...
  9. 《中国人工智能学会通讯》——11.34 基于近似动态规划的优化控制研究及 在电力系统中的应用...
  10. python400集视频教程-微软官方出品的400集Python精品视频教程,这正是我们急需的!...
  11. php自学好还是培训,转行php选择自学还是培训
  12. 对比修改过的两个BOM表
  13. Kotlin教程,从入门到精通
  14. google翻译退出中国后如何仍然使用windows版本
  15. 龙果 mycat mysql_龙果学院Spring Boot源码解析视频教程完整未加密(价值599)
  16. ttl接地是高电平还是低电平_说明图3.12中各门电路的输出是高电平还是低电平。已知它们都是74HC系列的CMOS电路 简单的逻辑门电路 判断各门电路...
  17. 计算机无法识别ipad2,win10系统无法识别iphone、ipad的修复方法
  18. 哔咔漫画怎样切换横屏?
  19. boundschecher2
  20. php 促销方案,七步就轻松搞定,促销活动方案

热门文章

  1. securecrt启动mini2440卡在Please press Enter to activate this console问题已解决
  2. assert利用蚁剑登录
  3. Salesforce考试丨Marketing Cloud管理员认证考试指南 exam guide(中文版)
  4. 【性能评估】ROC曲线
  5. 计算机和信息技术主题,主题二信息技术及其应用和发展.ppt
  6. 戴尔 Vostro 3470 成就商务台式机(i3-8100) 安装Win7系统
  7. 人人都是产品经理2.0-02章摘要总结
  8. 计算机无法识别相机,教您如果戴尔计算机无法检测到相机怎么办
  9. ORA-12899:value too large for column
  10. 【Java成王之路】EE初阶第二十三篇: HTTP协议和Tomcat