v-for: 根据数组的选项列表进行渲染,使用 item in items 语法,items 是源数组 item 是元素迭代的别名
<ul id="example-1">
<li v-for="item in items"> {{ item.message }} </li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
});
v-for 块中拥有对父作用域属性的完全访问权限。v-for 还支持一个可选的第二个参数为当前项的索引
<ul id="example-2">
/* 访问 data 数据中父作用域的 parentMessage 属性 */
<li v-for="(item, index) in items">{{parentMessage }}-{{index }}-{{ item.message }}</li>
</ul>
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
结果: Parent-0-Foo Parent-1-Bar
v-for中也可以用 of 替代 in 作为分隔符
<div v-for="item of items"></div>
对象的 v-for: 通过一个对象的属性来迭代
<ul id="v-for-object" class="demo">
<li v-for="value in object">{{ value }}</li>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
firstName: 'John',
lastName: 'Doe',
age: 30
}
}
})
结果:John Doe 30
第二个的参数为键名:
<div v-for="(value, key) in object">{{ key }}: {{ value }}</div>
第三个参数为索引:
<div v-for="(value, key, index) in object">{{ index }}. {{ key }}: {{ value }}</div>
key
1、当 v-for 正在更新已渲染过的元素列表时,它默认用"就地复用"策略
2、如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序
3、而是简单复用此处每个元素且确保它在特定索引下显示已被渲染过的每个元素
4、这个默认模式是高效的但只适用不依赖子组件状态或临时DOM状态 (表单输入值) 的列表渲染输出
5、为了给Vue提示,以便它跟踪每个节点的身份,重用和重新排序现有元素,要为每项提供唯一key属性
6、理想 key 值是每项都有的唯一 id,它是 Vue 识别节点的通用机制,key 并不与 v-for 特别关联
/* 所以需要用 v-bind 来绑定动态值 (在这里使用简写) */
<div v-for="item in items" :key="item.id">{{ item }}</div>
数组更新检测
变异方法: Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新
push() pop() shift()
unshift() splice() sort()
reverse()
替换数组
1、变异方法: 会改变被这些方法调用的原始数组
2、非变异方法: 如: filter(), concat() 和 slice()等不会改变原始数组,但总是返回一个新数组
/* 当使用非变异方法时,可以用新数组替换旧数组 */
example1.items = example1.items.filter( ( item ) => {
return item.message.match(/Foo/)
})
数组更改检测注意事项:Vue 不能检测手动添加的非响应式的数组
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的
Vue.set || vm.$set
必须用于向响应式对象中添加属性,并确保这个新属性是响应式的,且触发视图更新
注意!对象不能是 Vue 实例,或者 Vue 实例的根数据对象
Vue.set( vm.items, indexOfItem, newValue ) || vm.$set(vm.items, indexOfItem, newValue)
或者使用数组的变异方法
vm.items.splice(indexOfItem, 1, newValue) || vm.items.splice(newLength)
对象更改检测注意事项, Vue 不能检测对象属性的添加或删除
var vm = new Vue({
data: { a: 1 }
})
/* vm.a 现在是响应式的 */
/* vm.b = 2 不是响应式的 */
Vue.set || vm.$set
1、必须用于向响应式对象中添加属性,并确保这个新属性是响应式的,且触发视图更新
2、 注意,对象不能是 Vue 实例,或者 Vue 实例的根数据对象
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
Vue.set(vm.userProfile, 'age', 27) || vm.$set(vm.userProfile, 'age', 27)
为已有对象赋予多个新属性,比如使用 Object.assign() 或 _.extend()
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
显示过滤/排序结果: 显示数组的过滤或排序副本,而不改变或重置原始数据,可以创建返回过滤或排序数组的计算属性
<li v-for="n in evenNumbers">{{ n }}</li>
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}
在计算属性不适用的情况下 (例如,在 v-for 中) 可以使用一个 method 方法
<li v-for="n in even(numbers)">{{ n }}</li>
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
even(numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}
v-for 也可以取整数。在这种情况下,它将重复多次模板
<div><span v-for="n in 10">{{ n }}</span></div>
// 1 2 3 4 5 6 7 8 9 10
v-for on a <template’>: 可以利用带有 v-for 的 渲染多个元素
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
v-for vs v-if
当处于同一节点时, v-for 的优先级比 v-if 更高,意味着 v-if 分别重复运行于每个 v-for 中
/* 当为仅有的一些项渲染节点时,这种优先级的机制会十分有用 */
<li v-for="todo in todos" v-if="!todo.isComplete">{{ todo }}</li>
如果目的是有条件地跳过循环的执行,可以将 v-if 置于外层元素 (或 )上
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
在自定义组件里,可以像任何普通元素一样用 v-for
<my-component v-for="item in items" :key="item.id"></my-component>
任何数据不会自动传递到组件里,因为组件有自己独立的作用域.把迭代数据传递到组件里,要用 props
<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index"
v-bind:key="item.id"
>
</my-component>
不自动将 item 注入到组件里的原因是,这会使得组件与 v-for 的运作紧密耦合。明确组件数据的来源能够使组件在其他场合重复使用