MVVM框架设计分析(以vue.js为例 )

25 篇文章 0 订阅
9 篇文章 0 订阅

MVVM 框架设计

MVVM 框架已经成为前端圈的主流,同时也诞生了很多优秀的前端框架,有最早的Angular,以及后起之秀VueReact等,为我们开发者提供了极大的便利。那么,什么样的框架设计才算是MVVM框架呢?

MVVM框架的前身

最早使用Java开发的程序员应该了解过,当时有一种JSP动态脚本语言,是以JAVA语言作为载体,由服务端直出HTML网页的一种技术。下面是JSP的编写格式:

<html>
<head><title>Hello World</title></head>
<body>
<!-- 语法规则: <% 代码片段 %> -->
<% out.println("Your IP address is "); %> 

<br/>

<% out.println(request.getRemoteAddr()); %>
</body>
</html>

页面结果输出为: Your IP address is: xx.xx.xx.xx

可以看到这种脚本语言的一些特点:

  • 高耦合 (视图界面和功能逻辑互相糅合)
  • 复用性差
  • SEO相对较好 (服务端直出)

什么是MVVM

MVVM是一种程序设计框架。拆分出来就是:M-V-VM

  • M: Modal(数据模型层)
  • V: View (视图界面层)
  • VM: ViewModal(视图模型层)

下图是一个Vue框架的结构:

在这里插入图片描述
可以看出:

  • 视图(View)通过事件绑定影响数据模型(Modal)
  • 数据模型通过数据驱动渲染视图
  • 视图层数据模型层是相互独立的,通过视图模型进行关联

这种通过ViewModal相互影响的过程就是MVVM最大的特性(双向绑定)

数据驱动视图

作者认为,MVVM最大的特点就是它。无须操作DOM,只需修改数据,即可影响视图。

因为在这个框架出现之前,前端一直都是通过直接操作DOM,来影响视图的。这样做最大的弊端就是频繁操作DOM,会导致处理繁琐、代码冗余,而且如果DOM操作不当就会导致页面渲染性能下降。浏览器重绘和回流

比如实现场景:在input中输入某个值,对应显示在一个div中。我们就需要监听input值的变化,然后写入到对应的div中。

<script type="text/JavaScript">
function valChange(e){
	document.querySelector('#app').innerHTML =  e.target.value
}
</script>

<input type="text" id="a" oninput="valChange(event)" onporpertychange="valChange(event)" />
<div id="app"></div>

这种写法有一个最大的缺点就是视图层和我们的业务逻辑还是有糅合,如果需要最大化解耦,看看Vue如何去实现的:

<template>
<div>
	<!-- 视图模板 -->
	<input type="text" v-model="userName">
	<div>{{userName}}</div>
</div>

<script>
export default {
	data:{
		return {
			userName: '' // 数据模型
		}
	}
}
</script>
</template>

可以看到,当v-modal绑定的值发生改变时,页面会自动渲染更新对应的值。我们只需要声明视图模板,并且绑定对应的数据模型,那么我们的视图层就再也无需过多关心,这极大提升前端开发的工作效率。

点击此处进行测试

MVVM 的特点

1. 数据绑定

M-V-VM框架核心就是数据绑定,将ViewModal进行关联。数据绑定实现的关键就是指令,指令的职责是当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。因此,操作DOM相关的逻辑也是封装在指令中实现。参考 Vue.js 指令

在这里插入图片描述

Vue.js提供了指令机制: 用户可以通过具有特殊前缀的HTML 属性(v-htmlv-text等)来实现数据绑定,也可以使用常见的花括号({{}})模板插值,或是在表单元素上使用双向绑定(v-model)。

Vue会给动态更新的DOM节点创建对应的指令对象,当观测到指令对象的值发生变化时,它所绑定的目标节点就会执行对应的DOM操作。

2. 数据观测(监听)

数据观测(监听)的实现方式不同框架有不同的实现方式:一种是像Ng提出的脏检查(dirty checking) 机制,而Vue采用的是基于依赖收集的观测机制。此处重点讲解Vue的实现原理:

在这里插入图片描述

  • 数据劫持,将原生js对象改造成可观测对象
    实现手段有两种: ES5的Object.defineProperty方法以及ES6的Proxy方式(数据劫持实现原理)
  • 注册订阅者watcher求值过程中,每一个被取值的数据对象,都会将当前作用域的watcher作为自己的订阅者(写入到setter中),并成为当前watcher的一个依赖
  • 触发更新 当被依赖的数据对象进行赋值操作时,它会通知自己的watcher重新求值,并触发更新

概念

  1. watcher:用来观测数据的对象,叫做watcher
  2. 依赖收集: 通过重写getter、setter,将数据的依赖关系明确化,这样可以加快数据观察和更新的效率。
  3. 订阅者(dep): vueDep对象就是一种发布订阅者模式,订阅就是将watcher push到数组,发布就是将数组中的函数执行并popvue/dep.js实现源码

3.虚拟DOM

虚拟DOM就是为了解决浏览器性能问题(频繁操作DOM)而被设计出来的。页面性能大部分的性能瓶颈都在操作DOM上,而JS引起页面卡顿的很少有,如果有10个div节点依次插入到body中,每插入一个div都会导致页面重绘,可以想象如果有1000条数据同时加载,这样会严重影响用户体验。因此,Virtual DOM就是为了解决这个问题被设计出来的。

虚拟的DOM的核心思想是:对复杂的文档DOM结构,提供一种方便的实现,进行最小化地DOM操作。

4.组件

Vue.js的组件可以理解为预先定义好了行为的ViewModel类,例如vue.js比较流行的组件库(iVew)。

组件为开发者提供了可复用、可扩展的特征。vuejs 组件

组件的核心

  • 模板(template)
  • 数据(data)
  • 外部参数(props)
  • 方法(methods)
  • 钩子函数(hook function)

后记

本文只是简单的介绍了MVVM的设计思想,以及社区实现的项目。每个具体框架实现的细节这里也没有过多的展开,比如diff算法实现原理、模板编译相关,相关源码分析等。后续将会逐一展开进行讨论。

参考文档

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值