Vue学习笔记(二)
博客的markdown解释器显示有问题,请移步github
条件渲染
v-if
- 若truthy时渲染(truthy可以理解为
if(obj==true)
) - 与
<template>
标签配合,可y以一次if很多标签(虽然和<template>
本身定义的语义不太符合)
v-else
和if配合使用
<div v-if="Math.random() > 0.5">
Now you see me
</div>
<div v-else>
Now you don't
</div>
v-else-if
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
和if配合使用
v-show
与v-if不同,v-show
仅仅是控制元素的display
属性。
在某些情况下(比如需要频繁进行DOM操作),显然v-show
的效率更高。
在效果上,v-show
和自己用v-bind:style
来控制display
属性的最终效果相同。
对可复用的元素加上key
Vue可以用Key来复用元素,从而决定是否重新渲染。
对Key的设计,Vue是尽可能帮你复用元素,除非Key不同,而React恰好相反。
<li key='k1'></li>
列表渲染
列表渲染指令v-for
,示例如下:
<ul id="example-1">
<li v-for="item in items">
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
需要注意的是:
-
Vue不推荐将
v-for
和v-if
一起使用 -
v-for
支持可选的第二个参数,选项的索引<ul id="example-2"> <li v-for="(item, index) in items"> - - </li> </ul>
-
v-for
除了支持遍历数组,也可以遍历对象(的属性),和for...in
语法类似。此种用法支持最高三个参数:<div v-for="(value, name, index) in object"> . : </div>
-
Vue非常推荐给列表渲染时加上key
<div v-for="item in items" v-bind:key="item.id"> <!-- 内容 --> </div>
- 同样地,Vue默认行为是尽可能复用组件。
- 当无Key时,数据项的顺序被改变,Vue将不会移动DOM元素,而是就地更新。数据项大小变更,Vue将重新渲染。
- 使用Key,Vue就可以重用和重新排序现有元素。
更新检测
数组
-
对于变异方法(mutating method,即会改变数组本身的方法),比如
push
,pop
,shift
,unshift
,splice
等方法,Vue是通过将被监听的数组的变异方法进行包裹,从而实现更新检测。 -
对于非变异方法,比如
filter
,concat
,slice
等方法,一般用法是替换法,比如example1.items = example1.items.filter(item=>item.message.match(/Foo/))
这样主要依靠Vue的虚拟DOM来进行更新检测,通过Key复用从而提升性能
-
对于其他数组访问方法,将不能检测到更新监听(因为JS没有运算符重载):
- 直接用下标访问数组项
vm.items[index]=newValue
- 直接修改数组长度
vm.items.length=newLength
对于这两种数组访问,都可以使用
Array.prototype.splice
方法解决- 修改数组项
vm.items.splice(index,1,newValue)
- 修改数组长度
vm.items.splice(newLength)
- 直接用下标访问数组项
对象
-
由于JavaScript的限制,Vue不能检测对象属性的添加或删除,只能检测其修改(比如
Object.defineProperty
方法),所以在最开始定义时,就要将对象全部响应式属性定义出来,赋值为null
啥的都行。- 或者通过
Vue.set
方法,但我觉得不推荐,不够直观。提前定义vm中需要的数据,也是非常良好的习惯,对可读性的提升非常大。
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 现在是响应式的 vm.b = 2 // `vm.b` 不是响应式的
var vm = new Vue({ data: { a: 1, b: null//提前定义 } }) // `vm.a` 现在是响应式的 vm.b = 2 // `vm.b` 也是响应式的
- 或者通过
过滤/排序结果
许多需求是需要将列表结果通过过滤/排序重新显示,方法可以有:
-
计算属性
<li v-for="n in evenNumbers"></li>
data: { numbers: [ 1, 2, 3, 4, 5 ] }, computed: { evenNumbers: function () { return this.numbers.filter(function (number) { return number % 2 === 0 }) } }
-
方法属性
method
单纯重复
<!--渲染十次-->
<div>
<span v-for="n in 10"> </span>
</div>
使用模板
类似v-if
,v-for
也可以配合<template>
标签进行循环渲染
<ul>
<template v-for="item in items">
<li></li>
<li class="divider" role="presentation"></li>
</template>
</ul>
v-for
和v-if
一同使用
vue不推荐在同一元素上使用
v-for
和v-if
。
统一节点上的v-for
比v-if
优先级更高。即v-if
是作用于v-for
的循环中,而不是判断v-for
是否执行
事件处理
事件监听
使用v-on
指令监听DOM事件,类似DOM0级事件
<div id="example-1">
<button v-on:click="counter += 1">Add 1</button>
<p>The button above has been clicked times.</p>
</div>
当然更常见的是,将事件处理程序定义在methods
属性中,而不是写在v-on
指令里面。
- 不写调用,比如
v-on:click='hello'
,默认传入原生DOM事件event
,就像原生事件监听一样。 - 也可以写调用,
v-on:click='hello("QE")'
,则传入自己定义的参数。
事件修饰符
我们可以使用原生的event.preventDefault()
,event.stopPropagation()
,但Vue的事件绑定是用的DOM0级事件类似的语法。对addEventListener
的支持不太好,比如在捕获阶段处理事件等。Vue推出了一些事件修饰符实现对这些功能的支持:
-
.stop
=event.stopPropagation
-
.prevent
=event.preventDefault
-
.capture
=target.addEventListener(type,cb,true)
-
.self
:检测target,仅当target是元素自身才触发(即不是点击子元素) -
.once
:只调用一次即取消订阅 -
.passive
:对应target.addEventListener
的Option对象中的passive
属性,对于移动端性能优化有些用。passive
: ABoolean
which, iftrue
, indicates that the function specified bylistener
will never callpreventDefault()
. If a passive listener does callpreventDefault()
, the user agent will do nothing other than generate a console warning. See Improving scrolling performance with passive listeners to learn more.
修饰符语法可以串联:
<a v-on:click.stop.prevent="doThat">do That</a>
而且修饰符语法的顺序是有意义的。用 v-on:click.prevent.self
会阻止所有的点击,而 v-on:click.self.prevent
只会阻止对元素自身的点击。
按键修饰符
按键修饰符用于修饰键盘事件,指定按键,即keyup
,keydown
事件(keypress
事件已deprecated)。
<input v-on:keyup.enter="submit">
支持key value和key code两种按键定义,上式即是key value定义,更加可读,目前在标准里也更加推荐。
vue事件优化
虽然Vue的事件类似DOM0级事件,但不会导致任何的困难。当一个ViewModel被销毁时,所有的事件处理器会自动被删除。
表单绑定
使用v-model
指令在表单元素(<input>
,<textarea>
,<select>
等)元素上创建双向数据绑定,也就是所有的Vue表单都是受控表单。实现方法类似为:
- 监听用户输入事件,比如input事件、change事件,事件发生时更新对应vm数据
- 监听vm数据setter(可以通过
Object.defineProperty
),数据改变时更新表单数据。
<input v-model="message" placeholder="edit me">
<p>Message is: </p>