** 1.基本使用框架 **
所谓的数据驱动的理念:当数据发生变化的时候,用户界面也会发生相应的变化,开发者并不需要手动的去修改 dom .
简单的理解:就是 vue.js 帮我们封装了数据和 dom 对象操作的映射,我们只需要关心数据的逻辑处理,数据的变
谈谈你对MVVM开发模式的理解
** 2.MVVM分为Model、View、ViewModel三者 **
Model:代表数据模型,数据和业务逻辑都在Model层中定义;
View:代表UI视图,负责数据的展示;
ViewModel:负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作;
Mode和view并无直接关联,而是通过viewModel来进行联系的,Mode1和viewode1之间有着双向数据绑定的联系。因此当Mode1中的数据改变时会触发view层的刷新,view中由于用户交互操作而改变的数据也会在Model中同步。
这种模式实现了Model和View的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作dom。
简单的理解就是: MVVM 实现了将业务(数据)与视图进行分离的功能。
在这里还需要注意的一点就是:
MVVM 框架的三要素:响应式,模板引擎,渲染
- 响应式: vue 如何监听数据的变化?
- 模板: Vue 的模板如何编写和解析?怎样将具体的值替换掉 {{msg}} 内容,这就是模板引擎的解析。
- 渲染: Vue 如何将模板转换成 html ? 其实就是有虚拟 DOM 向真实 DOM 的转换。
在后面的课程中,我们还会深入探讨这块内容,包括我们自己模拟实现一个数据驱动的框架
** 3.属性绑定 **
属性的绑定,下面先来看一下关于对属性的绑定
<div id="app">
<h2 v-bind:title="msg">
{{msg}}
</h2>
</div>
在上面的代码中,我们通过 v-bind 的方式给 h2 绑定了一个 title 属性。
当然,上面的代码我们也可以使用如下的方式来进行简化
<div id="app">
<h2 :title="msg">
{{msg}}
</h2>
</div>
为了避免闪烁的问题,也就是最开始的时候,出现: {{msg}} 的情况,可以使用如下的绑定方式
<div id="app">
<h2 :title="msg">
<!-- {{msg}} -->
<span v-text="msg"></span>
</h2>
</div>
** 4.列表渲染 **
我们可以使用 v-for 指令基于一个数组来渲染一个列表. v-for 指令需要使用 item in items 形式的语法。其中items 是源数组,而 item 则是被迭代的数组元素的别名。
基本实现的代码如下:
注意:为了能够保证列表渲染的性能,我们需要给 v-for 添加 key 属性。 key 值必须唯一,而且不能使用index 与 random 作为 key 的值。
关于这一点是与虚拟 DOM 算法密切相关的。在后面的课程中会最为一个重点来探讨虚拟 DOM 的内容。这也是面试
的时候经常被问到的问题。
** 5.v-model **
其实这就是我们常说的,“双向数据绑定”
<!-- v-model指令用来双向数据绑定:就是model和view中的值进行同步变化 -->
<!-- v-model只能在input/textarea/selet 也就是表单元素-->
怎样验证v-model实现了双向数据绑定呢?
可以打开控制台,然后输入: vm.userName 发现输出的值为 “zhangsan”, 取的是模型中的数据。
当在文本框中输入新的值后,在敲一下 vm.userName 发现对应的数据发生了变化,也就是视图中的数据发生了变
化,模型中的数据也 会发生变化。
那么在控制台中直接给 vm.userName=“lisi”, 发现文本框中的值也发生了变化。
** 6.v-on **
还可以通过简写的形式。建议以后都使用简写的形式
<button @click="changeName">更换姓名</button>
带参数的形式如下:
除了绑定鼠标的单击事件以外,也可以绑定键盘的实际。
例如,页面有有一个文本框,用户在该文本框中输入内容,按下回车键,获取到用户输入的内容
在 mehtods 中定义 changeUserName 方法
** 7、Class与Style绑定 **
这块主要内容主要与样式设置有关。
操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute ,所以我们可以用
v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v- bind 用于 class 和 style 时, Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
下面先来看一下 Class 的绑定。
在"列表渲染"中给每个列表项添加对应的样式
<style>
.actived {
background-color: #dddddd;
}
</style>
下面给 li 列表添加上面所定义的样式。
<li
v-for="(item,index) in users"
:key="item.id"
:class="{actived:true}"
>
> 编号:{{item.id}} 姓名:{{item.name}}---索引:{{index}}
</li>
在上面的代码中,我们可以看到,给 li 标签绑定了 class 属性,同时 actived 的值为 true ,表示给 li 添加actived 样式。
现在有一个需求,就是当鼠标移动到列表项上的时候,更改对应的背景色。
<li
v-for="(item,index) in users"
:key="item.id"
:class="{actived:selectItem===item}"
@mousemove="selectItem=item"
>
完整代码
下面,我们再来看一下 Style 的绑定。
** 8.条件渲染 **
v-if和v-show指令可以用来控制元素的显示和隐藏
下面,我们先来看一下 v-if 的应用。
这里还是对用户数据进行判断。
上面是关于 v-if 的使用,下面看一下 v-show .
v-show 是通过 css 属性 display 控制元素显示,元素总是存在的。
v-if :通过控制 dom 来控制元素的显示和隐藏,如果一开始条件为 false ,元素是不存在的。
什么时候使用 v-show ,什么时候使用 v-if 呢?
1.如果需要频繁的控制元素的显示与隐藏,建议使用 v-show . 从而避免大量 DOM 操作,提高性能。
2.而如果某个元素满足条件后,渲染到页面中,并且以后变化比较少,可以使用 v-if
** 9.计算属性 **
- 计算属性出现的目的是解决模板中放入过多的逻辑会让模板过重且难以维护的问题.
- 计算属性是根据data中已有的属性,计算得到一个新的属性.
计算属性实现:
使用计算属性还有一个好处:
其实细心的话就会发现,调用methods里的方法也能实现和计算属性一样的效果,既然使用methods就可以实
现,那为什么还需要计算属性呢?原因就是计算属性是基于他的依赖缓存的(所依赖的还是 data 中的数据)。一
个计算属性所依赖的数据发生变化时,他才会重新取值
也就是说:只要相关依赖没有改变,对此访问计算属性得到的是之前缓 存的结果,不会多次执行。
** 10.侦听器 **
侦听器就是侦听 data 中的数据变化,如果数据一旦发生变化就通知侦听器所绑定方法,来执行相应的操作。从这一点上,与计算属性是非常类似的。
但是,侦听器也有自己独有的应用场景。
执行异步或开销较大的操作。
我们使用侦听器来统计总人数。
<p>
总人数:{{totalCount}}
</p>
在 data 中定义 totalCount 属性。
data: {
selectItem: "",
num: 100,
totalCount: 0
}
使用 watch 来监听 users 数组的数据变化。
watch: {
users: {
immediate: true, //立即执行
handler(newValue, oldValue) {
this.totalCount = newValue.length + "个人";
},
},
}
当 users 数组发生了变化后,就会执行 handler 这个函数,同时用于加上了 immediate 属性,并且该属性的值
为 true ,表示的就是在初始化绑定的时候,也会去执行侦听器。因为 watch 在初始化绑定的时候是不会执行
的,等到所监听的内容改变之后才会去侦听执行。
以上就是 watch 侦听器的基本使用,但是通过这个案例,我们发现还是使用计算属性来统计总人数更加的方便一
些。
下面我们在通过一个案例,来体会一下 watch 侦听器的应用场景。
下面我们来看一个异步操作的情况。就是当用户在一个文本框中输入了用户名以后,要将输入的用户名发送到服务
端,来检查该用户名是否已经被占用。
具体的实现代码如下:
以上的案例,就是通过 watch 来监听 uname 的值是否发生变化,如果发生了变化,就通过发送异步请求来检查
uname 中的值,是否已经被占用。
通过以上的案例:我们可以看到 watch 是允许异步操作的,并且在我们得到最终的结果前,可以设置中间状态,
这些都是计算属性无法做到的。
最后我们把计算属性与侦听器做一个总结,看一下它们的应用场景。
第一点:语境上差异
- watch 适合一个值发生了变化,对应的要做一些其它的事情,适合一个值影响多个值的情形。
例如,上面案例中的用户名检测,这里是一个 uname 发生了变化,但是这里做了很多其它的事情,例如修改
message 的值,发送异步请求。
- 而计算属性 computed :一个值由其它的值得来,其它值发生了变化,对应的值也会变化,适合做多个值影响一个值的情形。
例如如下代码:
computed:{
fullName(){
return this.firstName+' '+this.lastName
}
}
第二点:计算属性有缓存性。
- 由于这个特点,我们在实际的应用中,能用计算属性的,会首先考虑先使用计算属性
第三点:
- 侦听器选项提供了更加通用的方法,适合执行异步操作或者较大开销操作。