一、使用v-for遍历数组生成元素
标题
使用 v-for 指令,将一个数组渲染为列表项。
v-for 指令需要限定格式为 item in items 的特殊语法,items是原始数据数组,item是数组中每个迭代元素的指代别名。
<div id="app1">
<li v-for="item in items">
{{ item.message }}
</li>
</div>
----------
var app1 = new Vue({
el: '#app1',
data: {
items: [
{message:'Foo'},
{message:'Bar'}
]
}
})
第二个参数作为索引
<div id="app2">
<li v-for="(item,index) in items">
{{parentMessage}} - {{index}} - {{item.message}}
</li>
</div>
----------
var app2 = new Vue({
el: '#app2',
data: {
parentMessage: 'Hello!',
items: [
{message: 'Foo'},
{message: 'Bar'}
]
}
})
结果是

of作分隔符
可以不使用 in而是使用 of 作为分隔符。
of更加接近 JavaScript 迭代器语法。
<div id="app3">
<li v-for="item of items">
{{item.message}}
</li>
</di
----------
var app3 = new Vue({
el: '#app3',
data: {
items: [
{message: 'Foo'},
{message: 'Bar'}
]
}
})
二、使用v-for遍历对象
基本语法
使用 v-for 来遍历对象的属性。
<div id="app4">
<li v-for="value in object">
{{value}}
</li>
</div>
----------
var app4 = new Vue({
el: '#app4',
data: {
object:{
firstname: 'Dong',
lastname: 'Yu',
age: '20'
}
}
})
提供第二个参数作为对象的键名
<div id="app5">
<li v-for="(value,key) in object">
{{key}} : {{value}}
</li>
</div>
----------
var app5 = new Vue({
el: '#app5',
data:{
object:{
no1: 'Dong Yu',
no2: 'Dong xixi',
no3: 'Dong momo'
}
}
})
结果为:

提供第三个参数作为索引
在遍历一个对象时,是按照 Object.keys() 得出 key 的枚举顺序来遍历,无法保证在所有 JavaScript 引擎实现中完全一致。
<div id="app6">
<li v-for="(value,key,index) in object">
{{index+1}} - {{key}} - {{value}}
</li>
</div>
----------
var app6 = new Vue({
el: '#app6',
data:{
object:{
firstname: 'Dong',
lastname: 'Yu',
age: '20'
}
}
})
三、key
就池原则
当 Vue 更新已使用 v-for 渲染的元素列表时,默认会采用“就地填充”策略。
如果数据项的顺序发生了变化,不是移动 DOM 元素来匹配列表项的顺序,而是Vue 会将每个元素填充到恰当的位置,最终反映为,在该特定索引处放置应该呈现的内容。
这个默认模式是高效率的,但是只适用于当你的列表渲染输出不依赖于子组件状态或临时 DOM 状态(例如,表单输入值)时。
key属性
需要重新复用和重新排序现有元素 —— 需要 Vue 跟踪每个节点的身份 —— 为每项提供唯一的 key 属性
理想的 key 值是每项都有唯一的 id。
这是个特殊属性需要使用 v-bind 将其与动态值绑定在一起。(因为是属性)
<div id="app7">
<li v-for="item in items" :key="item.id"></li>
</div>
在使用 v-for 时尽可能提供一个 key,除非迭代的 DOM 内容足够简单,或者你是故意依赖于默认行为来获得性能提升。
key 不限于与 v-for 关联,还可以其他场景使用。
四、数组变化检测
变化数组方法
变化数组方法在调用后会改变原始数组。
Vue将观察数组的变化数组方法包裹起来,以便在调用这些方法时,也能够触发视图更新。这些包裹的方法如下:
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
可以打开控制台,然后对前面示例中的 items 数组调用变化数组方法。
例如:example1.items.push({ message: ‘Baz’ })。
替换一个数组
非变化数组方法 (例如 filter(), concat() 和 slice())不会直接修改操作原始数组而是返回一个新数组。
可以将旧数组替换为新数组。
<div id="app8">
<li v-for="item in items">
{{item.message}}
</li>
<button @click="change()">切换</button>
</div>
---------
var app8 = new Vue({
el: "#app8",
data:{
items:[
{message:"Foo"},
{message:"Bar"}
]
},
methods:{
change:function(){
this.items = this.items.filter(function(item){
return item.message.match(/Foo/)
})
}
}
})
Vue**并不是**丢弃现有 DOM 并重新渲染整个列表 。
Vue 实现了一些智能启发式方法来最大化 DOM 元素重用。
将一个数组替换为包含重叠对象的另一个数组是一种非常高效的操作。
注意事项
由于 JavaScript 的限制,Vue 无法检测到以下数组变动:
- 当你使用索引直接设置一项时,例如 vm.items[indexOfItem] = newValue
- 当你修改数组长度时,例如 vm.items.length = newLength
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是响应的
vm.items.length = 2 // 不是响应的
解决方法如下:
- 使用索引直接设置一项
方法一:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
方法二:
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
方法三:
vm.$set(vm.items, indexOfItem, newValue)
- 修改数组长度
vm.items.splice(newLength)
五、对象变化检测
受现代 Javascript 的限制, Vue 无法检测到对象属性的添加或删除。
var vm = new Vue({
data: {
a: 1
}
})
// `vm.a` 是响应的
vm.b = 2
// `vm.b` 不是响应的
Vue 不允许在已经创建的实例上动态地添加新的根级响应式属性。
添加响应式属性
可以使用 Vue.set方法将响应式属性添加到嵌套的对象上。
还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名。
<div id="app9">
<li v-for="item in items">{{item}}</li>
</div>
----------
var app9 = new Vue({
el: '#app9',
data: {
items: {
name: 'Dong Yu'
}
}
})
Vue.set(app9.items,'age',20)
向已存在的对象添加新属性
创建一个新的对象,这个对象同时具有两个对象的所有属性。
Object.assign(vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
//添加新的响应式属性:
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
六、显示过滤/排序结果
computed属性
显示一个数组过滤或排序后的副本,而不是实际改变或重置原始数据,可以创建一个返回过滤或排序数组的计算属性。
<div id="app10">
<li v-for="n in evenNumbers">
{{n}}
</li>
</div>
----------
var app10 = new Vue({
el: '#app10',
data:{
number: [1,2,3,4,5,6,7,8,9]
},
computed: {
evenNumbers:function(){
return this.number.filter(function(num){
return num % 2 === 0
})
}
}
})
methods方法
在计算属性不适用的情况下(例如,在嵌套的 v-for 循环内),可以使用一个 method 方法。
<div id="app11">
<li v-for="n in even(numbers)">
{{n}}
</li>
</div>
----------
var app11 = new Vue({
el: '#app11',
data: {
numbers: [1,2,3,4,5,6,7,8,9]
},
methods:{
even: function(numbers){
return numbers.filter(function(num){
return num % 2 === 0
})
}
}
})
七、在整数值范围内迭代
<div id="app12">
<li v-for="n in 10">
{{n}}
</li>
</div>
结果为 1 2 3 4 5 6 7 8 9 10
八、在< template >中使用v-for
渲染多个元素块
<div id="app13">
<template v-for="item in items">
<li>{{item.msg}}</li>
<li>我不是响应式的</li>
</template>
</div>
----------
var app13 = new Vue({
el: '#app13',
data: {
items:[
{msg:'啦啦啦'},
{msg:'嘻嘻嘻'}
]
}
})
结果为

九、带有v-if的v-for
将某些项渲染为节点
当它们都处于同一节点时,v-for 的优先级高于 v-if。
v-if 将分别在循环中的每次迭代上运行。
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
根据条件跳过执行循环
将 v-if 放置于包裹元素上(或放置于 < template > 上)
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
本文详细介绍了Vue.js框架中v-for指令的使用方法,包括如何遍历数组和对象生成DOM元素,如何利用key属性提高列表更新效率,以及如何处理数组和对象的变化。此外还探讨了在不同场景下使用v-for的最佳实践。
1202

被折叠的 条评论
为什么被折叠?



