MyException - 我的异常网
当前位置:我的异常网» 设计模式 » 说MVVM

说MVVM

www.MyException.Cn  网友分享于:2013-09-19  浏览:0次
谈MVVM

什么是MVVM

MVVM模型-视图-视图模型,Model-View-ViewModal)是一种架构模式,并非一种框架,它是一种思想,一种组织与管理代码的艺术。它利用数据绑定,属性依赖,路由事件,命令等特性实现高效灵活的架构

一个事件发生的过程:

1、用户在视图 V 上与应用发生交互

2、VM 触发相应的事件,VM从模型 M 中请求到用户需要的数据,并立马反馈回视图

3、视图 V 更新数据,展现给用户

Mvvm的核心是数据驱动,实际开发中,只要预先写好viewmodel的关系映射(viewmodel),然后viewmodl为核心,从view出发,页面需要什么数据,就去model中设置数据源。当发生了用户事件时,view处理自己的用户接口事件,并把相关事件映射到视图模型。viewmodl通知更新model,然后刷新view 从而实现数据双向绑定更新

 

概念简介

一)模型

模型持有着应用的多个领域下的相关数据。一个领域相关的数据,说白了,是用户账号(名字,头像,电子邮件)的抽象,或者音乐唱片(唱片名,年代,专辑)的抽象模型是一个领域下的数据及其相关逻辑的抽象。当视图模型请求数据时,模型将数据包装成模型实例,

model本身是独立的,自控的,不依赖于view,能够同步支持多view的显示。

 

二)视图

视图是与用户交互的一层。它是展现一个视图模型状态的一个可交互视图包含数据绑定用户接口事件,还需要能够理解视图模型的行为尽管这些行为能够被映射到属性处理这来自视图模型的事件。

 

三)视图模型核心

视图模型是一个专门进行数据转换的控制器。它把对象信息转换到视图信息,将命令从视图携带到对象。

例子:有一个对象的日期属性是unix格式的(e.g 1333832407),不是用户视图的所需要的日期格式(e.g 04/07/2012 @ 5:00pm),转换为视图需要的格式。我们的对象只简单保存原始的unix数据格式日期,视图模型作为一个中间人角色会格式化原始的unix数据格式转换为视图需要的日期格式。

在这个场景下,视图模型相当于一个对象,它处理多视图显示逻辑也对外提供更新视图状态的方法,并通过视图方法和触发事件更新对象。

Vue描述视图模型作为数据的表现和操作可以在UI上访问和执行。视图模型并不是一个UI对象,也不是数据持久化对象,而是一个能够为用户提供储存状态及操作的层次对象。Vue的视图模型实现了JavaScript对象与HTML语言无关性。通过这个实现使开发保持了简单

 

为什么会出现 MVVM 呢?

一切源于h5的流行,与原生app进行快速迭代。既然要用H5 来构建 App, View 层所做的事,就不仅仅是简单的数据展示了,它不仅要管理复杂的数据状态,还要处理移动设备上各种操作行为等等。因此,前端需要工程化,传统的MVC模式:

    1. View 展示数据
    2. Model 管理数据
    3. Controller 响应用户操作,并将 Model 更新到 View 上

但是,当应用上升到一个级别时,mvc模式的弊端有3个明显的问题:

1代码中大量调用相同的 DOM API,代码难以维护。

2大量的DOM 操作使页面加载速度变慢,影响用户体验。

3Model 的频繁变化,需要开发者主动更新到View ;当用户的操作导致 Model 发生变化,开发者同样需要将变化的数据同步到Model 。 当UI 状态一旦多起来时,工作不仅繁琐,而且很难维护复杂多变的数据状态。

关于对MVC比较详细的理解,这里请参考我写的上一篇文章简单谈谈Mvc

 

为了解决上述问题,出现了前端界的MVVMMVVM 可以很好的降低我们维护状态视图的复杂程度(大大减少代码中的视图更新逻辑)。

下面还是以todoListdemo和上篇文章的例子对比,实现同样的功能,用到的js代码不到30

 1 <template>
 2     <div id="app">
 3         <ul v-for="(item, index) in todoList">
 4             <li @click="remove(index)">{{item.text}}</li>
 5         </ul
 6         <input type="text" v-model="text">
 7         <button @click="add">确认</button>
 8     </div>
 9 </template>
10 
11 <script>
12   import store from './data_store.js'
13 
14   const TODO_LIST = '__todoList__'
15   export default {
16     data() {
17       return {
18         text: '',
19         todoList: store.get(TODO_LIST, [])
20       }
21     },
22 
23     methods: {
24       add() {
25         let val = this.todoList.push({
26           id: Number(new Date()),
27           text: this.text && this.text.trim()
28         })
29         this.text = ''
30       },
31       remove(index) {
32         this.todoList.splice(index, 1)
33       }
34     },
35     watch: {
36       todoList() {
37         store.set(TODO_LIST, this.todoList)
38       }
39     }
40   }
41 </script>
 1 /*
 2  * 只封了 get 与 set
 3  */
 4 let store = {
 5   storage: window.localStorage
 6 }
 7 
 8 const api = {
 9   /*
10    * @param key 为localStorage 的key值
11    * @param defaults 当本地存储的数据为空时的默认值 
12    */
13   get(key, defaults) {
14     let val = deserialize(this.storage.getItem(key))
15     return val !== undefined ? val : defaults
16   },
17 
18   set(key, val) {
19     if (typeof val === "undefined") {
20      return this.remove(key)
21     }
22     this.storage.setItem(key, serialize(val))
23   },
24 
25   remove(key) {
26     this.storage.removeItem(key)
27   }
28 }
29 
30 function serialize(val) {
31   return JSON.stringify(val)
32 }
33 
34 function deserialize(val) {
35   if (typeof val !== "string") {
36     return
37   }
38   return JSON.parse(val)
39 }
40 
41 Object.assign(store, api)
42 
43 export default store

解决什么?

    对于一定数量功能的网页,合理高效组织代码,是提高开发效率的关键所在。在事件管理上面,MV*注重模型的数据改变而触发各种事件,将数据和事件联系起来,数据变动,界面变化。面向数据编程,把所有精力放在数据处理,不关心对网页元素的处理。MVVM更加便于UI和驱动UI的构造块这两部分的并行开发抽象视图使得背后所需要的业务逻辑(或者粘合剂)的代码数量得以减少对于持续集成项目,你不光要考虑到初次开发,还要考虑功能演进和可交接性

       从前端地角度,它是UI模式解决方案在前端,我们经常要处理数据与界面的关系。mv的完全脱离,使得开发人员只专于注业务逻辑,抽象的数据,依靠vmv的双向绑定,通过改变业务逻辑,界面就自动更新了,尤其方便。故开发人员需要维护的只是抽象数据,通过数据,可以随时构建出新的 UI 。  UI 的状态一旦多起来mvvm这种优势就体现出来了。

     当下优秀的MVVM框架有很多,不同的业务场景采用不同框架,它们有一个始终统一的目的:解放dom操作,面向数据编程。这里以vue为例,在同一业务逻辑下,通过vue很好地解决了mv的耦合,其高可复用性,一个viewModal可以复用到多个view视图上。开发人员只关注viewModal,结合其生态系统中的vue-routervuex更好地组织代码。纯粹讲MVVM的概念太多抽象了,在下一篇文章,我会通过实现一个简单的vue来模拟mvvm的实践。

1楼天边里
支持一个!哈哈

文章评论

团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
10个调试和排错的小建议
10个调试和排错的小建议
程序员都该阅读的书
程序员都该阅读的书
那些争议最大的编程观点
那些争议最大的编程观点
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
 程序员的样子
程序员的样子
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
我是如何打败拖延症的
我是如何打败拖延症的
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
程序员必看的十大电影
程序员必看的十大电影
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
一个程序员的时间管理
一个程序员的时间管理
Java程序员必看电影
Java程序员必看电影
程序员和编码员之间的区别
程序员和编码员之间的区别
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
每天工作4小时的程序员
每天工作4小时的程序员
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
鲜为人知的编程真相
鲜为人知的编程真相
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
代码女神横空出世
代码女神横空出世
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
编程语言是女人
编程语言是女人
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
程序员的鄙视链
程序员的鄙视链
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
总结2014中国互联网十大段子
总结2014中国互联网十大段子
旅行,写作,编程
旅行,写作,编程
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
程序员应该关注的一些事儿
程序员应该关注的一些事儿
漫画:程序员的工作
漫画:程序员的工作
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有