Vue中列表渲染v-for详解

HarryZhang 2019年06月27日 205次浏览

用 v-for 把一个数组对应为一组元素

我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名 如果你有使用过jstl类似的库就非常好理解。

<ul id="app">
    <li v-for="user in users">
        {{user.id}}--{{user.name}}
    </li>
</ul>

var vm = new Vue({
    el: "#app",
    data: {
    users: [
            { id: "1", name: "jack" },
            { id: "2", name: "tom" },
            { id: "3", name: "HarryZhang" }
        ]
    }
})

结果:

  • 1--jack
  • 2--tom
  • 3--HarryZhang

v-for 还支持一个可选的第二个参数,即当前项的索引。

    <ul id="app">
        <li v-for="(user,index) in users">
            {{user.id}}--{{user.name}}--{{index}}
        </li>
    </ul>

结果:

  • 1--jack--0
  • 2--tom--1
  • 3--HarryZhang--2

你也可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法

<div v-for="item of items"></div>

在 v-for 里使用对象

你也可以用 v-for 来遍历一个对象的属性。

<ul id="app">
    <li v-for="(item) in coder">{{item}}</li>
</ul>
var vm = new Vue({
    el: "#app",
    data: {
    coder:{
        name:"HarryZhang",
        age:19,
        gender:"男"
        }
    }
})

结果:

  • HarryZhang
  • 19

你也可以提供第二个的参数为 property 名称 (也就是键名):

<ul id="app">
    <li v-for="(key,value) in coder">{{key}}:{{value}}</li>
</ul>

结果:

  • name:HarryZhang
  • age:19
  • gender:男

还可以用第三个参数作为索引

<div v-for="(value, key, index) in coder">
  {{ index }}. {{ key }}: {{ value }}
</div>

结果:

  • 0.name:HarryZhang
  • 1.age:19
  • 2.gender:男
在遍历对象时,会按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。

维护状态

v-for中我们知道有一个key属性,那他到底是干什么的呢?

下面是官方给出的解释:

当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。这个类似 Vue 1.x 的 track-by="$index"。这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。

其实就是给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性:

下面写了一个demo,每次向一个数组最前面中加一个对象

<div id="app">
    id:<input type="text" v-model="id">
    name: <input type="text" v-model="name">
    <button @click="add">添加</button>
    <!-- 数据展示 -->
    <p v-for="item in items">
        <input type="checkbox">
        {{item.id}}--{{item.name}}
    </p>
</div>
var vm = new Vue({
    el: "#app",
    data: {
        id:"",
        name:"",
        items:[
            {id:1,name:"tom"},
            {id:2,name:"jack"},
            {id:3,name:"lucy"}
        ]
    },
    methods: {
        add(){
            this.items.unshift({id:this.id,name:this.name})
            }
        }
})

当我们点击添加时就会向数组前面丢一个对象

demo1

我们先默认选中任意一个chekbox,然后添加一下一个对象

demo2

最后得到结果demo3

看出什么没? 顺序乱了,这个时候就需要指定一个key

<div v-for="item in items" v-bind:key="item.id"> <!-- 内容 --> </div>

然后再测试一下: demo4

ok

key就相当于绑定了一个id。

建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

注意:

2.2.0+ 的版本里,当在组件上使用 v-for 时,key 现在是必须的

不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值。

在 v-for 里使用值范围

v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数。

<div> <span v-for="n in 10">{{ n }} </span> </div>

结果: 12345678910