1、条件渲染
(1)v-if
v-if 指令 用于条件性(根据表达式的值)渲染内容,可以与 v-else 指令 和 v-else-if 指令 一同使用
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <p v-if="type === 'A'">A</p> <p v-else-if="type === 'B'">B</p> <p v-else-if="type === 'C'">C</p> <p v-else>Else</p> </div> <script> new Vue({ el: '#app', data: { type: 'A' } }) </script> </body> </html>
(2)v-if & v-show
v-show 指令 同样可以根据表达式的真假渲染内容
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <p v-show="isSeen">A</p> </div> <script> new Vue({ el: '#app', data: { isSeen: true } }) </script> </body> </html>
它们不同之处在于:v-if
是直接添加或删除 DOM 元素,而 v-show
是修改元素的 display 属性
因此,v-if
适用于相对稳定的元素,v-show
适用于频繁切换的元素
(3)template
v-if
是一个指令,因此必须添加到一个元素上,如果希望同时添加到多个元素上该怎么办呢?
可以使用 <template>
元素当做不可见的包裹元素,并在上面使用 v-if
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <template v-if="isOk"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template> </div> <script> new Vue({ el: '#app', data: { isOk: true } }) </script> </body> </html>
2、列表渲染
v-for 指令 用于渲染一个列表
(1)使用数组
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <ul> <li v-for="item in items"> {{ item.message }} </li> </ul> </div> <script> var vm = new Vue({ el: '#app', data: { items: [ { message: 'Hello' }, { message: 'Hi' } ] } }) </script> </body> </html>
v-for 用于数组时,还支持可选的第二个参数,即当前项的索引:v-for="(item, index) in items"
(2)使用对象
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <ul> <li v-for="value in object"> {{ value }} </li> </ul> </div> <script> var vm = new Vue({ el: '#app', data: { object: { firstName: 'Steve', lastName: 'Jobs' } } }) </script> </body> </html>
v-for 用于对象时,还支持一个可选的第二个参数,即当前项的键:v-for="(value, key) in object"
还支持一个可选的第三个参数,即当前项的索引:v-for="(value, key, index) in object"
(3)使用整数
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <span v-for="n in 10">{{ n }} </span> </div> <script> var vm = new Vue({ el: '#app' }) </script> </body> </html>
(4)维护状态
当 Vue 正在更新使用 v-for
渲染的元素列表时,它默认使用 “就地更新” 的策略
也就是说,如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序
而是就地更新每个元素,并且确保它们在每个索引位置正确渲染
因此为了跟踪每个节点,我们需要为每一个项提供一个唯一的 key
(一般使用基本属性作为 key
)
<div v-for="item in items" v-bind:key="item.id"> <!-- 内容 --> </div>
(5)数组 更新检测
对于数组而言,使用变异方法会自动触发视图更新,变异方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
// 可以尝试在控制台中直接对前面的例子调用变异方法 vm.items.push({ message: 'Goodbye'})
而使用非变异方法则总是返回一个新数组,可以使用新数组替代旧数组以触发视图更新,非变异方法包括:
filter()
concat()
slice()
// 可以尝试在控制台中对前面的例子调用非变异方法,使用新数组替代旧数组 vm.items = vm.items.filter(function (item) { return item.message.match(/Hi/) })
注意,还有以下两种情况不能检测数组的变化:
- 利用索引设置数组的值,例如
vm.items[indexOfItem] = newValue
- 修改数组的长度,例如
vm.items.length = newLength
这时,我们都可以使用变异方法 splice()
解决:
- 利用索引设置数组的值,
vm.items.splice(indexOfItem, 1, newValue)
- 修改数组的长度,
vm.items.splice(newLength)
(6)对象 变更检测
以下的情况同样不能检测对象的变化:
- 添加对象属性,例如
vm.newValue = value
(此时,newValue 不是响应式属性)
这时,我们可以使用实例方法 vm.$set
解决:
- 添加对象属性,
vm.$set(object, propertyName, value)
文章知识点与官方知识档案匹配,可进一步学习相关知识