列表渲染
v-for
我们可以使用 v-for
指令根据数组渲染项目列表。v-for
指令需要使用 item in items
形式的特殊语法,其中 items
是源数据数组,item
是正在迭代的数组元素的 **别名**
示例
|
|
结果
- {{item.message}}
在 v-for
块内,我们可以完全访问父作用域属性,以及一个特殊的变量 $index
,它表示当前项目的数组索引
|
|
结果
- {{ parentMessage }} - {{ $index }} - {{ item.message }}
或者,你也可以为索引(或 v-for
用于对象时的键)指定一个别名
|
从 1.0.17 版本开始,你也可以使用 of
作为分隔符,而不是 in
,使其更接近 JavaScript 迭代器的语法
|
模板 v-for
类似于模板 v-if
,你也可以使用带有 v-for
的 <template>
标签来渲染多个元素的块。例如
|
数组变更检测
变异方法
Vue.js 包装了被观察数组的变异方法,以便它们也会触发视图更新。被包装的方法是
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
你可以在控制台中使用之前的示例的 items
数组,通过调用它的变异方法来进行操作。例如:example1.items.push({ message: 'Baz' })
。
替换数组
变异方法,顾名思义,会改变它们被调用的原始数组。相比之下,也有一些非变异方法,例如 filter()
、concat()
和 slice()
,它们不会改变原始数组,而是 **始终返回一个新的数组**。在使用非变异方法时,你可以用新数组替换旧数组
|
你可能会认为这会导致 Vue.js 丢弃现有的 DOM 并重新渲染整个列表 - 幸运的是,情况并非如此。Vue.js 实现了一些智能启发式算法,以最大限度地重用 DOM 元素,因此用包含重叠对象的另一个数组替换数组是一个非常高效的操作。
track-by
在某些情况下,你可能需要用完全新的对象替换数组 - 例如,从 API 调用创建的对象。由于默认情况下 v-for
通过跟踪其数据对象的标识来确定现有作用域和 DOM 元素的可重用性,这会导致整个列表被重新渲染。但是,如果你的每个数据对象都有一个唯一的 id 属性,那么你可以使用 track-by
特殊属性来提示 Vue.js,以便它可以尽可能地重用现有实例。
例如,如果你的数据如下所示
|
那么你可以这样给出提示
|
稍后,当你替换 items
数组时,Vue.js 遇到一个新的对象,其 _uid: '88f869d'
,它知道可以重用与相同 _uid
关联的现有作用域和 DOM 元素。
track-by $index
如果你没有唯一的键来跟踪,你也可以使用 track-by="$index"
,这将强制 v-for
进入就地更新模式:片段不再移动,它们只是用对应索引的新值刷新。此模式也可以处理源数组中的重复值。
这可以使数组替换非常高效,但它也有一些权衡。由于 DOM 节点不再移动以反映顺序的变化,因此 DOM 输入值和组件私有状态等临时状态可能会不同步。因此,在使用 track-by="$index"
时要小心,如果 v-for
块包含表单输入元素或子组件。
注意事项
由于 JavaScript 的限制,Vue.js **无法** 检测到对数组的以下更改
- 当你直接用索引设置一个项目时,例如
vm.items[0] = {}
; - 当你修改数组的长度时,例如
vm.items.length = 0
。
为了处理注意事项 (1),Vue.js 为被观察数组添加了一个 $set()
方法
|
为了处理注意事项 (2),只需用一个空数组替换 items
即可。
除了 $set()
之外,Vue.js 还为数组添加了一个便捷方法 $remove()
,它通过内部调用 splice()
来搜索并从目标数组中删除一个项目。因此,与其
|
你可以直接做
|
使用 Object.freeze()
当迭代一个用 Object.freeze()
冻结的对象数组时,你需要显式地使用 track-by
键。当 Vue.js 无法自动跟踪对象时,在这种情况下会显示一个警告。
对象 v-for
你也可以使用 v-for
来迭代对象的属性。除了 $index
之外,每个作用域都可以访问另一个特殊属性 $key
。
|
|
结果
- {{ $key }} : {{ value }}
你也可以为键提供一个别名
|
当迭代一个对象时,顺序基于 Object.keys()
的键枚举顺序,这 **不** 保证在所有 JavaScript 引擎实现中都是一致的。
范围 v-for
v-for
也可以接受一个整数。在这种情况下,它将重复该模板多次。
|
结果
显示过滤/排序的结果
有时我们只需要显示数组的过滤或排序版本,而不需要实际改变或重置原始数据。有两种方法可以实现这一点
- 创建一个返回过滤或排序数组的计算属性;
- 使用内置的
filterBy
和orderBy
过滤器。
计算属性将为你提供更细粒度的控制和更大的灵活性,因为它完全是 JavaScript;但过滤器对于常见用例来说可能更方便。有关数组过滤器的详细用法,请查看它们的 文档。