谈MVVM
来源:互联网 发布:兜率宫的正确读音 知乎 编辑:程序博客网 时间:2024/06/05 06:17
什么是MVVM?
MVVM(模型-视图-视图模型,Model-View-ViewModal)是一种架构模式,并非一种框架,它是一种思想,一种组织与管理代码的艺术。它利用数据绑定,属性依赖,路由事件,命令等特性实现高效灵活的架构
一个事件发生的过程:
1、用户在视图 V 上与应用发生交互
2、VM 触发相应的事件,VM从模型M 中请求到用户需要的数据,并立马反馈回视图
3、视图 V 更新数据,展现给用户
Mvvm的核心是数据驱动,实际开发中,只要预先写好view和model的关系映射(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模式:
- View 展示数据
- Model 管理数据
- Controller 响应用户操作,并将 Model 更新到 View 上
但是,当应用上升到一个级别时,mvc模式的弊端有3个明显的问题:
1、代码中大量调用相同的 DOM API,代码难以维护。
2、大量的DOM操作使页面加载速度变慢,影响用户体验。
3、Model 的频繁变化,需要开发者主动更新到View;当用户的操作导致 Model发生变化,开发者同样需要将变化的数据同步到Model中。 当UI 状态一旦多起来时,这些工作不仅繁琐,而且很难维护复杂多变的数据状态。
关于对MVC比较详细的理解,这里请参考我写的上一篇文章:简单谈谈Mvc
为了解决上述问题,出现了前端界的MVVM。MVVM可以很好的降低我们维护状态,视图的复杂程度(大大减少代码中的视图更新逻辑)。
下面还是以todoList为demo和上篇文章的例子对比,实现同样的功能,用到的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 : defaults16 },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 return37 }38 return JSON.parse(val)39 }40 41 Object.assign(store, api)42 43 export default store
解决什么?
对于有一定数量功能的网页,合理,高效地组织代码,是提高开发效率的关键所在。在事件管理上面,MV*注重模型的数据改变而触发各种事件,将数据和事件联系起来,数据变动,界面变化。面向数据编程,把所有精力放在数据处理,不关心对网页元素的处理。MVVM更加便于UI和驱动UI的构造块,这两部分的并行开发,抽象视图使得背后所需要的业务逻辑(或者粘合剂)的代码数量得以减少,对于持续集成项目,你不光要考虑到初次开发,还要考虑功能演进和可交接性。
从前端地角度,它是UI模式的解决方案,在前端,我们经常要处理数据与界面的关系。m与v的完全脱离,使得开发人员只专于注业务逻辑,抽象的数据,依靠vm与v的双向绑定,通过改变业务逻辑,界面就自动更新了,尤其方便。故开发人员需要维护的只是抽象数据,通过数据,可以随时构建出新的 UI 。 当 UI 的状态一旦多起来时,mvvm这种优势就体现出来了。
当下优秀的MVVM框架有很多,不同的业务场景采用不同框架,它们有一个始终统一的目的:解放dom操作,面向数据编程。这里以vue为例,在同一业务逻辑下,通过vue很好地解决了m与v的耦合,其高可复用性,一个viewModal可以复用到多个view视图上。开发人员只关注viewModal,结合其生态系统中的vue-router与vuex更好地组织代码。纯粹讲MVVM的概念太多抽象了,在下一篇文章,我会通过实现一个简单的vue来模拟mvvm的实践。
- 谈MVVM
- 谈MVVM
- MVVM
- MVVM
- MVVM
- MVVM
- MVVM
- MVVM
- MVVM
- MVVM
- mvvm
- MVVM
- MVVM
- mvvm
- MVVM
- MVVM
- MVVM
- MVVM
- 区别系统的“稳定性、鲁棒性、与非脆弱性”
- instanceof用法
- 算法 1.3.46 栈的可生成性问题
- Java Message Service(ActiveMQ 1)
- 62个jQuery代码开发技巧收集
- 谈MVVM
- 沉浸式状态栏
- 欢迎使用CSDN-markdown编辑器
- 佛祖保佑 永无BUG
- mybatis与spring整合时读取properties问题的解决
- 「python」文件的重命名、删除
- eclipse不会自动下载jar包
- DHTML(Dynamic HTML)--4.表单(form)的校验与提交
- Chrome浏览器在加载本地资源时报错Not allowed to load local的原因以及解决办法。