3.MVVM模式
3.1 介绍
- MVVM(Model View-ViewModel))是-种软件架构设计模式,由微软WPF(用于替代
VinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight(类似于Java Applet,简单点
说就是在浏览器上运行的WPF)的架构师Ken Cooper和Ted Peters开发,是一种简化用户界面
的事件驱动编程方式。由John Gossman(同样也是WPF和Silverlight的架构师)于2005年在
他的博客上发表 - MVVM源自于经典的MVC(Model-View-Controller)模式。MVVM的核心是ViewModel
层,负责转换Modl中的数据对象来让数据变得更容易管理和使用,其作用如下: -
- 该层向上与视图层进行双向数据绑定
- 向下与Mode|层通过接口请求进行数据交互
注意:哪两层绑定?
MVVM已经相当成熟了,主要运用但不仅仅在网络应用程序开发中。当下流行的MVVM框架有
Vue.js,Angular]S等。
3.3 为什么要使用MVVM
- MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大好处:
-
- 低耦合:视图(View)可以独立于Mode变化和修改,一个ViewMode|可以绑定到不同的
View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。 - 可复用:你可以把一些视图逻辑放在一个ViewMode|里面,让很多View重用这段视图逻辑。
- 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewMod),设计人员可以专注于页
面设计。 - 可测试:界面素来是比较难于测试的,而现在测试可以针对ViewMode|来写。
MVVM的组成部分
- 低耦合:视图(View)可以独立于Mode变化和修改,一个ViewMode|可以绑定到不同的
3.3 各层功能
- View层
View是视图层,也就是用户界面。前端主要由HTML和CSS来构建,为了更方便地展现
ViewModel或者Model层的数据,已经产生了各种各样的前后端模板语言,比如FreeMarker
hymeleaf等等,各大MVVM框架如Vue.js,AngularJS,EJS等也都有自己用来构建用户界面的
内置模板语言。
- Model
Model是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展
开。这里的难点主要在于需要和前端约定统一的接口规则
- ViewModel:数据双向绑定
- ViewMode|是由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者对从后端获取的Mode|数据进行转换处理,做二次封装,以生成符合View层使用预期的视图数据模型。
- 需要注意的是ViewModel所封装出来的数据模型包括视图的状态和行为两部分,而Model层的数据模型是只包含状态的
- 比如页面的这一块展示什么,那一块展示什么这些都属于视图状态(展示)
- 页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互)
- 视图状态和行为都封装在了ViewModel里。这样的封装使得ViewModel可以完整地去描述
view层。由于实现了双向绑定,viewModel的内容会实时展现在View层,这是激动人心的,因为前端开发者再也不必低效又麻烦地通过操纵DOM去更新视图。- MVVM框架已经把最脏最累的一块做好了,我们开发者只需要处理和维护ViewModel,更新数据视图就会自动得到相应更新,真正实现事件驱动编程。
- View层展现的不是Model层的数据,而是ViewMode1的数据,由ViewModel负责与Model
层交互,这就完全解耦了View层和Mod!层,这个解耦是至关重要的,它是前后端分离方案实施的
重要一环。
3.4 MVVM模式的实现者
- Mode:模型层,在这里表示JavaScript对象
- View:视图层,在这里表示DOM(HTML操作的元素)
- ViewModel:连接视图和数据的中间件,Vue.js就是MVVM中的ViewModel层的实现者在MVVM架构中,是不允许数据和视图直接通信的,只能通过ViewModel来通信,而ViewModel就是定义了一个Observer观察者
- ViewModel能够观察到数据的变化,并对视图对应的内容进行更新
- ViewMode|能够监听到视图的变化,并能够通知数据发生改变
- 因此:Vue.js就是一个MVVM的实现者,他的核心就是实现了DOM监听与数
据绑定
3.5为什么要使用Vue.js
- 轻量级,体积小是一个重要指标。Vue,js压缩后有只有20多kb(Angular压缩后56kb+,
React压缩后44kb+) - 移动优先。更适合移动端,比如移动端的Touch事件
- 易上手,学习曲线平稳,文档齐全
- 吸取了Angular(模块化)和React(虚拟DOM)的长处,并拥有自己独特的功能,如:计算
属性 - 开源,社区活跃度高
3.6 vue例子
- 用hbuilder创建一个普通的工程,导入vue.js,之后创建一个测试页面
- idea需要安装vue插件
注意:Vue不支持IE8及以下悵本,因为Vue使用了IE8无法模拟的ECMAScript5特性。但
它支持所有兼容ECMAScript5的浏览器。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue2</title>
</head>
<body>
<!-- view层,模板 -->
<div id="msg">
{{msg}}
</div>
</body>
<!-- 导入vue.js -->
<script src="static/vue.js"></script>
<script>
/* vm对象 */
const apps = new Vue({
el: '#msg',
/* model层数据 */
data: {
msg: 'hello vue'
}
})
</script>
</html>
之前HTML等静态页面,在与后台交互时通过操作dom元素来进行的,而vue通过vm来绑定视图和模型,观察模型数据变化同步到视图,监听视图变化来通知模型,从而不直接操作dom元素
-
测试:为了能够更直观的体验Vue带来的数据绑定功能,我们需要在浏览器测试一番,操作流程如下:
-
- 在浏览器上运行第一个Vue应用程序,进入开发者工具
- 在控制台输入vm.message=‘Hello World’,然后回车,你会发现浏览器中显示的内容会直接变成Hello World
- 此时就可以在控制台直接输入vm.message来修改值,中间是可以省略data的,在这个操作中,我并没有主动操作DOM,就让页面的内容发生了变化,这就是借助了Vue的数据绑定功能实现的;MVVM模式中要求ViewModl层就是使用观察者模式来实现数据的监听与绑定,以做到数据与视图的快速响应。
3.7 v-bind
- 在上面例子中,vue在渲染数据时做了大量工作,使得数据和dom元素关联,数据的变动到页面响应都是响应式的。在控制台操作对象属性,界面能够实时响应。
- 另外可以用v-bind绑定元素属性,简写 :class=“color”
注意:需要将模板放到el元素选择标签内部
注:使用V-*绑定属性数据是不需要双花括号包裹的,若绑定值数据,而在后面要使用则需使用模板{{}}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue2</title>
</head>
<body>
<!-- view层,模板 -->
<div id="msg">
{{msg}}{{name}}
<span v-bind:title="msgs" v-bind:class="color">
鼠标悬浮试试
</span>
</div>
</body>
<!-- 导入vue.js -->
<script src="static/vue.js"></script>
<script>
/* vm对象 */
const vm = new Vue({
el: '#msg',
/* model层数据 */
data: {
msg: 'hello vue',
name: ' tonyss',
msgs: '提示文字',
color: 'reds'
}
})
</script>
<style type="text/css">
.reds{
color: red;
}
.blues{
color: blue;
font-size: 18px;
}
</style>
</html>
- 你看到的v-bind等被称为指令。指令带有前缀v-,以表示它们是Vue提供的特殊特性。它们会在渲染的DOM上应用特殊的响应式行为。在这里,该指令的意思是:“将这个元素节点的title特性和Vue实例的message属性保持一致”。
3.8 v-if/v-for
- v-if
- v-else-if
- v-else
- v-for=”(item,index) in items
注:===三个等号在JS中表示绝对等于(就是数据与类型都要相等)
注:items是数组,item是数组元素迭代的别名。之后学习的Thymeleaf模板引擎的语法和这个十分的相似
控制台可以通过push方法来给vm新加值vm.items.push({msg:‘hadoop’})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<p v-if="ok">ture</p>
<p v-else>false</p>
<p v-if="num > 80">优秀</p>
<p v-else-if="num > 60">及格</p>
<p v-else-if="num < 60">不及格</p>
<p v-else>无成绩</p>
<p v-for="(item,index) in items">
{{item.msg}}---{{index}}
</p>
</div>
<script src="static/vue.js"></script>
<script>
/* vm对象 */
const vm = new Vue({
el: '#app',
data: {
ok: false,
num: 0,
items: [
{msg: 'java'},
{msg: 'python'},
{msg: 'C#'}
]
}
})
</script>
</body>
</html>
3.9 绑定事件
- v-on:click=“functionName” 简写:@click=“functionName”
- v-on监听事件事件有Vue的事件、和前端页面本身的一些事件!我们这里的click是vue的事件,可以绑定到Vue中的methods中的方法事件!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue2</title>
</head>
<body>
<!-- view层,模板 -->
<div id="msg">
{{msg}}{{name}}
<span v-bind:title="msgs" v-bind:class="color">
鼠标悬浮试试
</span>
<p v-if="say">请说一段语言</p>
<a v-bind:href="url">点我链接...</a>
<div @click="click1">
<div @click.stop="click2">
点我按钮...
</div>
</div>
<div v-on:click="click3">
点我按钮3...
</div>
<div class="c1" v-bind:class="[isActive?'active':'',isYello?'yello':'']">
class区域
</div>
<div class="c1" v-bind:style="{color:v1,backgroundcolor:isYello?'aquamarine':''}">
class区域
</div>
<div v-for="item,index in Data" :key="index">
{{index}}---{{item.messae}}
</div>
<div v-for="value,key in Obj" :key="key">
{{key}}:{{value}}
</div>
<button v-on:click="counts += 1">add1{{counts}}</button>
<button v-on:click="greet('123',$event)">点击事件</button>
</div>
</body>
<!-- 导入vue.js -->
<script src="static/vue.js"></script>
<script>
/* vm对象 */
const vm = new Vue({
el: '#msg',
/* model层数据 */
data: {
msg: 'hello vue',
name: ' tonyss',
msgs: '提示文字',
color: 'reds',
say: true,
url: 'https://cn.vuejs.org/',
isActive: true,
isYello: true,
v1: 'red',
Data: [{messae: 'java'},{messae: 'phyton'}],
Obj: {
title: 'haha',
author: 'lisi',
option: 'read'
},
counts: 1
},
methods: {
click1: function (){
console.log('click1')
},
click2: function (){
console.log('click2')
},
greet: function (str,e){
alert(str)
console.log(e)
},
click3: function (){
console.log('click3')
}
}
})
</script>
<style type="text/css">
.reds{
color: red;
}
.blues{
color: blue;
font-size: 18px;
}
.active{
width: 200px;
height: 50px;
line-height: 50px;
background-color: antiquewhite;
text-align: center;
}
.c1{
font-size: 28px;
}
.yello{
color: yellow;
}
</style>
</html>
下一篇:Vue-03-数据双向绑定/组件
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123880.html