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

我们用 v-for 指令根据一组数组的选项列表进行渲染。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' }]}
})

结果:

  • Foo
  • Bar

在 v-for 块中,我们拥有对父作用域属性的完全访问权限。v-for 还支持一个可选的第二个参数为当前项的索引。

<ul id="example-2"><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

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

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

一个对象的 v-for

你也可以用 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>

firstName: John

lastName: Doe

age: 30

第三个参数为索引:

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

0. firstName: John

1. lastName: Doe

2. age: 30

在遍历对象时,是按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下是一致的。

key

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个类似 Vue 1.x 的 track-by="$index" 。

这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的唯一 id。这个特殊的属性相当于 Vue 1.x 的 track-by ,但它的工作方式类似于一个属性,所以你需要用 v-bind 来绑定动态值 (在这里使用简写):

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

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

因为它是 Vue 识别节点的一个通用机制,key 并不与 v-for 特别关联,key 还具有其他用途,我们将在后面的指南中看到其他用途。

数组更新检测

变异方法

Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

你打开控制台,然后用前面例子的 items 数组调用变异方法:example1.items.push({ message: 'Baz' }) 。

替换数组

变异方法 (mutation method),顾名思义,会改变被这些方法调用的原始数组。相比之下,也有非变异 (non-mutating method) 方法,例如:filter()concat() 和 slice() 。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:

example1.items = example1.items.filter(function (item) {return item.message.match(/Foo/)
})

你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的、启发式的方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

注意事项

由于 JavaScript 的限制,Vue 不能检测以下变动的数组:

  1. 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength

举个例子:

var vm = new Vue({data: {items: ['a', 'b', 'c']}
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的

为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

你也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:

vm.$set(vm.items, indexOfItem, newValue)

为了解决第二类问题,你可以使用 splice

vm.items.splice(newLength)

对象更改检测注意事项

还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除

var vm = new Vue({data: {a: 1}
})
// `vm.a` 现在是响应式的vm.b = 2
// `vm.b` 不是响应式的

对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性。例如,对于:

var vm = new Vue({data: {userProfile: {name: 'Anika'}}
})

你可以添加一个新的 age 属性到嵌套的 userProfile 对象:

Vue.set(vm.userProfile, 'age', 27)

你还可以使用 vm.$set 实例方法,它只是全局 Vue.set 的别名:

vm.$set(vm.userProfile, 'age', 27)

有时你可能需要为已有对象赋予多个新属性,比如使用 Object.assign() 或 _.extend()。在这种情况下,你应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性,不要像这样:

Object.assign(vm.userProfile, {age: 27,favoriteColor: 'Vue Green'
})

你应该这样做:

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: function (numbers) {return numbers.filter(function (number) {return number % 2 === 0})}
}

一段取值范围的 v-for

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-if,你也可以利用带有 v-for 的 <template> 渲染多个元素。比如:

<ul><template v-for="item in items"><li>{{ item.msg }}</li><li class="divider" role="presentation"></li></template>
</ul>

v-for with v-if

当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用,如下:

<li v-for="todo in todos" v-if="!todo.isComplete">{{ todo }}
</li>

上面的代码只传递了未完成的 todos。

而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 <template>)上。如:

<ul v-if="todos.length"><li v-for="todo in todos">{{ todo }}</li>
</ul>
<p v-else>No todos left!</p>

一个组件的 v-for

了解组件相关知识,查看 组件。完全可以先跳过它,以后再回来查看。

在自定义组件里,你可以像任何普通元素一样用 v-for 。

<my-component v-for="item in items" :key="item.id"></my-component>

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

然而,任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要用 props :

<my-componentv-for="(item, index) in items"v-bind:item="item"v-bind:index="index"v-bind:key="item.id"
></my-component>

不自动将 item 注入到组件里的原因是,这会使得组件与 v-for 的运作紧密耦合。明确组件数据的来源能够使组件在其他场合重复使用。

下面是一个简单的 todo list 的完整例子:

<div id="todo-list-example"><form v-on:submit.prevent="addNewTodo"><label for="new-todo">Add a todo</label><inputv-model="newTodoText"id="new-todo"placeholder="E.g. Feed the cat"><button>Add</button></form><ul><liis="todo-item"v-for="(todo, index) in todos"v-bind:key="todo.id"v-bind:title="todo.title"v-on:remove="todos.splice(index, 1)"></li></ul>
</div>

注意这里的 is="todo-item" 属性。这种做法在使用 DOM 模板时是十分必要的,因为在 <ul> 元素内只有 <li> 元素会被看作有效内容。这样做实现的效果与 <todo-item> 相同,但是可以避开一些潜在的浏览器解析错误。查看 DOM 模板解析说明 来了解更多信息。

Vue.component('todo-item', {template: '\<li>\{{ title }}\<button v-on:click="$emit(\'remove\')">Remove</button>\</li>\',props: ['title']
})new Vue({el: '#todo-list-example',data: {newTodoText: '',todos: [{id: 1,title: 'Do the dishes',},{id: 2,title: 'Take out the trash',},{id: 3,title: 'Mow the lawn'}],nextTodoId: 4},methods: {addNewTodo: function () {this.todos.push({id: this.nextTodoId++,title: this.newTodoText})this.newTodoText = ''}}
})

Add a todo  Add

  • Do the dishes Remove
  • Take out the trash Remove
  • Mow the lawn Remove

from: https://cn.vuejs.org/v2/guide/list.html

Vue.js 列表渲染相关推荐

  1. js array 添加对象_不可不知的 Vue.js 列表渲染

    介绍 用 v-for 把一个数组对应为页面上的一组元素 vue.js 使用的是 v-for 指令来处理组件元素的循环迭代逻辑.通常它会和 v-if 配合使用,达到我们所需要的处理逻辑. v-for 的 ...

  2. Vue.js列表渲染指令v-for

    目录 一.原理概述 二.基本用法 (1)v-for循环普通数组 (2)v-for循环对象 (3)v-for循环对象数组 (4)v-for迭代整数 一.原理概述 v-for指令时在模板编译的代码生成阶段 ...

  3. vue使用html渲染组件,Vue.js在渲染组件之前填充数据

    我是Vue.js的新手,我试图创建一个没有成功的简单组件,它包含一个selectList,我试图填充它的选项数据来模拟Ajax请求,这是我的代码:Vue.js在渲染组件之前填充数据 HTML {{n. ...

  4. 【Vue】—列表渲染v-for指令

    [Vue]-列表渲染v-for指令

  5. Vue.js服务器端渲染与Vue路由器:分步指南

    当我开始使用Vue收集有关SSR(服务器端渲染)的信息时,我必须从不同的文章以及官方文档中获取相关信息,以便全面了解这个主题. 以下是我在这些来源中发现的一些问题: 很多关于你应该拥有的信息的假设,比 ...

  6. Vue的列表渲染指令

    列表渲染指令 v-for 当需要将一个数组便利或者枚举一个对象循环显示时,就会用到列表渲染指令  v-for. 它的表达式需要结合in 来使用,类似于item in items的形式. <!do ...

  7. Vue 6. 列表渲染

    本文主要包含以下知识点: 使用 v-for 进行列表渲染 数组更新检测 使用 v-for 进行列表渲染 使用 v-for 指令根据一组数组的选项列表进行渲染.v-for 指令需要使用 item in ...

  8. Vue.js 条件渲染

    v-if 在字符串模板中,比如 Handlebars,我们得像这样写一个条件块: <!-- Handlebars 模板 --> {{#if ok}}<h1>Yes</h1 ...

  9. vue学习- 列表渲染v-for

    v-for用法 可操作的对象: 数组(普通数组,对象数组).对象.数字: 以对象数组为例: let arr=[{name:'张三',age:'18',sex:'男'},{name:'李思',age:' ...

最新文章

  1. Lagrange equation
  2. AI对人类社会的真正威胁
  3. pr扫光转场插件_2020年最新pr转场特效:300套模板+200集视频教程+插件,送你参考...
  4. 路由热备份(HSRP)DynamipsGUI小试牛刀
  5. [css] 设置字体时为什么建议设置替换字体?
  6. 电商优秀设计作品展示
  7. Linux经常使用命令(十六) - whereis
  8. 空间点到直线的距离c语言,空间两直线间距离公式(文档篇).doc
  9. 蛋糕网店/蛋糕店管理系统/蛋糕销售系统
  10. Latex: 添加IEEE会议论文作者信息
  11. 01-03Python编程:操作列表
  12. 【跟我一起学Unity3D】做一个2D的90坦克大战之地图编辑器
  13. 获苹果中国区推荐,能带来多少新增
  14. 数据库 连接(自然连接,内连接,外连接)
  15. 【BIOS】MBR引导程序类型及详解
  16. 同源策略 - 学习/实践
  17. 《OpenCV3编程入门》学习笔记之书本资源汇总
  18. 5W3H法与SMART原则的结合使用
  19. Suggestion: use tools:overrideLibrary
  20. 2021年中国国有企业经营现状分析:营业收入及利润总额均增加[图]

热门文章

  1. 大数据分析:Java 下降,华为平均月薪高达 35K,分析 89 万招聘数据有这些发现!
  2. 巨杉数据库 CTO 王涛:区块链+数据库,底层技术融合是否带来更大爆发?
  3. 你能活多少岁,就让人工智能来告诉你吧
  4. 借由AI招聘软件,这位CEO 48h 内从4000名求职者中锁定那一位
  5. 搜索业务增速下滑 Google廉颇老矣?
  6. 供应链金融服务平台:应收、预付和存货融资业务
  7. Spring-使用外部属性文件01
  8. 改计算机用户头像,Windows 8.1
  9. git指定版本openwrt源码_[OpenWrt Wiki] LEDE源代码
  10. forward和redirect有什么区别?