通常情况下我们需要将一个数组或者对象循环显示的时候,就会用到这个列表渲染指令v-for。它的表达式需要和in或者of结合使用。
- 数组渲染
首先我们看一个关于数组渲染的例子,这也是最常见的使用形式:
<template>
<ul>
<li v-for="book in books">{{book.name}}</li>
</ul>
</template>
<script>
export default {
name: "Vfor",
data() {
return{
books: [
{name: '<<Vue 实战指南>>'},
{name: '<<Java 实战指南>>'},
{name: '<<C++ 实战指南>>'}
]
}
}
}
</script>
程序运行结果:
这里我们解释一下这段代码的含义,其中我们定义了一个books的数组用来存放我们的书籍数据,book是我们当前数组元素的别名,循环出的每个li标签内的元素都可以访问对应的book数据。
其中上面的in也可以使用of来代替,这一点更符合JavaScript的语法:
<li v-for="book of books">{{book.name}}</li>
前一段时间我刚接触vue的时候,就拿上面的例子说,我就想给每个列表元素的前面加上各自的索引,其实在vue中我们可以为我们的表达式添加一个可选参数作为当前项的索引,如下:
<li v-for="(book,index) of books">{{index}}---{{book.name}}</li>
效果图:
这里顺便说一下,在vue1.x的版本中可以直接使用$index,在vue2.x的版本中废弃了这一用法。
- 对象渲染
和数组渲染的写法有细微的差异,我们通过实例代码来学习:
<template>
<ul>
<li v-for="(value,key,index) in book">{{index}}--{{key}}:{{value}}</li>
</ul>
</template>
<script>
export default {
name: "Vfor",
data() {
return {
book: {
name: 'Vue 实战指南',
author: '尤雨溪',
publish_date: '2017-10-1'
}
}
}
}
</script>
这里我们定义了一个book对象,然后在列表中渲染。
在这个(value,key,index) 表达式中,key和index是可选参数,其中key是对象属性的名称,index是索引。
运行效果:
另外有个实用的小用法是利用v-for来迭代整数,例如:
<li v-for="n in 10">{{n}}</li>
这里我们是显示了1-10的整数:
在这里我们说明一下关于数组数据的更新需要注意的两点:
- 通过索引直接设置项,vue不能检测到,不会更新视图
this.books[0] = {name: this.modify_name}
- 通过修改数组长度,vue不能检测到,不会更新视图
this.books.length = 1
对于第一种情况,我们可以有针对性的进行修改,还是上面的例子我们可以修改对应元素的相关属性来达到更新视图的目的:
这里我把代码重新贴一次,方便大家查看:
<template>
<div>
<div>
<input v-model="modify_name">
<button @click="modify">确认修改</button>
</div>
<ul>
<li v-for="(book,index) of books">{{index}}---{{book.name}}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Vfor",
data() {
return {
books: [
{name: '<<Vue 实战指南>>'},
{name: '<<Java 实战指南>>'},
{name: '<<C++ 实战指南>>'}
],
modify_name: ''
}
},
methods: {
modify: function () {
this.books[0].name = this.modify_name
}
}
}
</script>
我们增加了一个输入框和一个按钮,点击按钮我们会修改列表的第一项的内容,运行效果:
输入新的名称,然后点击修改:
下面列出了通过代码使用相关方法操作数组时候会触发视图更新的方法:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
使用上面的方法会改变原始数组的数据,下面几个方法则不会改变原始数组:
filter()
concat()
slice()
它们会返回一个新的数组。
下面我们还是修改上面的例子,实现对列表进行简单的过滤和者排序:
<template>
<div>
<p>原始数组:</p>
<ul>
<li v-for="book in books">{{book.name}}</li>
</ul>
<p>排序后的数组:</p>
<ul>
<li v-for="book in sortBooks">{{book.name}}</li>
</ul>
<p>过滤后的数组:</p>
<ul>
<li v-for="book in filterBooks">{{book.name}}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Vfor",
data() {
return {
books: [
{name: '<<Vue 实战指南>>'},
{name: '<<Java 实战指南>>'},
{name: '<<Java 实战指南2>>'},
{name: '<<C++ 实战指南>>'},
{name: '<<C++ 实战指南2>>'}
],
search_name: ''
}
},
computed: {
filterBooks: function () {
return this.books.filter(function (book) {
return book.name.match(/Java/)
})
},
sortBooks: function () {
return this.sortKey(this.books,'name')
}
},
methods: {
sortKey: function (array,key) {
return array.sort(function (a,b) {
var book1 = a[key]
var book2 = b[key]
return book1.length < book2.length
})
}
}
}
</script>
<style scoped>
</style>
运行效果:
代码比较简单,我们就不细说了。