指南
基础
- 安装
- 介绍
- Vue 实例
- 模板语法
- 计算属性和侦听器
- 类和样式绑定
- 条件渲染
- 列表渲染
- 事件处理
- 表单输入绑定
- 组件基础
组件深入
- 组件注册
- Props
- 自定义事件
- 插槽
- 动态和异步组件
- 处理边缘情况
过渡和动画
- 进入/离开和列表过渡
- 状态过渡
可重用性和组合
- 混入
- 自定义指令
- 渲染函数和 JSX
- 插件
- 过滤器
工具
- 单文件组件
- 测试
- TypeScript 支持
- 生产部署
扩展
- 路由
- 状态管理
- 服务器端渲染
- 安全
内部机制
- 深入响应性
迁移
- 从 Vue 1.x 迁移
- 从 Vue Router 0.7.x 迁移
- 从 Vuex 0.6.x 迁移到 1.0
- 迁移到 Vue 2.7
元数据
- 与其他框架的比较
- 加入 Vue.js 社区!
- 认识团队
列表渲染
使用 v-for
将数组映射到元素
我们可以使用 v-for
指令根据数组渲染项目列表。v-for
指令需要使用 item in items
形式的特殊语法,其中 items
是源数据数组,item
是正在迭代的数组元素的 **别名**
|
|
结果
- {{item.message}}
在 v-for
块内,我们可以完全访问父作用域属性。v-for
还支持可选的第二个参数来表示当前项目的索引。
|
|
结果
- {{ parentMessage }} - {{ index }} - {{ item.message }}
你也可以使用 of
作为分隔符而不是 in
,使其更接近 JavaScript 的迭代器语法
|
使用对象的 v-for
你也可以使用 v-for
迭代对象的属性。
|
|
结果
- {{ value }}
你也可以提供第二个参数来表示属性的名称(也称为键)
|
以及另一个参数来表示索引
|
迭代对象时,顺序基于 Object.keys()
的枚举顺序,这 **不** 保证在不同的 JavaScript 引擎实现中保持一致。
维护状态
当 Vue 更新使用 v-for
渲染的元素列表时,默认情况下它使用“就地修补”策略。如果数据项的顺序发生了变化,Vue 不会移动 DOM 元素以匹配项的顺序,而是会就地修补每个元素并确保它反映了该特定索引处应该渲染的内容。这类似于 Vue 1.x 中 track-by="$index"
的行为。
这种默认模式效率很高,但 **仅适用于列表渲染输出不依赖于子组件状态或临时 DOM 状态(例如表单输入值)的情况**。
为了给 Vue 一个提示,以便它可以跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每个项目提供一个唯一的 key
属性
|
建议在可能的情况下为 v-for
提供 key
属性,除非迭代的 DOM 内容很简单,或者你故意依赖默认行为以提高性能。
由于它是一种通用的机制,用于 Vue 识别节点,因此 key
还有其他用途,这些用途并不专门与 v-for
相关,我们将在本指南的后面部分看到。
不要使用对象和数组等非原始值作为 v-for
键。请改用字符串或数字值。
有关 key
属性的详细用法,请参阅 key
API 文档。
数组变更检测
变异方法
Vue 包装了被观察数组的变异方法,以便它们也会触发视图更新。包装的方法是
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
你可以在控制台中打开并使用前面的示例的 items
数组,通过调用它们的变异方法。例如:example1.items.push({ message: 'Baz' })
。
替换数组
变异方法顾名思义,会改变它们被调用的原始数组。相比之下,还有一些非变异方法,例如 filter()
、concat()
和 slice()
,它们不会改变原始数组,而是 **始终返回一个新数组**。在使用非变异方法时,你可以用新数组替换旧数组
|
你可能会认为这会导致 Vue 丢弃现有的 DOM 并重新渲染整个列表 - 幸运的是,情况并非如此。Vue 实现了一些智能启发式方法,以最大限度地重用 DOM 元素,因此用包含重叠对象的另一个数组替换数组是一个非常高效的操作。
注意事项
由于 JavaScript 的限制,Vue **无法检测** 数组和对象中的某些类型的更改。这些在 响应性 部分中讨论。
显示过滤/排序的结果
有时我们希望显示数组的过滤或排序版本,而实际上并不改变或重置原始数据。在这种情况下,你可以创建一个计算属性,它返回过滤或排序后的数组。
例如
|
|
在计算属性不可行的情况下(例如在嵌套的 v-for
循环中),你可以使用方法
|
|
使用范围的 v-for
v-for
也可以接受一个整数。在这种情况下,它会重复该模板指定的次数。
|
结果
在 <template>
上使用 v-for
类似于模板 v-if
,你也可以使用 <template>
标签与 v-for
一起渲染多个元素的块。例如
|
v-for
与 v-if
请注意,**不** 建议将 v-if
和 v-for
放在一起使用。有关详细信息,请参阅 风格指南。
当它们存在于同一个节点上时,v-for
的优先级高于 v-if
。这意味着 v-if
将在循环的每次迭代中分别运行。这在你想仅为某些项目渲染节点时很有用,如下所示
|
上面的代码只渲染未完成的任务。
如果你的意图是条件性地跳过循环的执行,你可以将 v-if
放在包装元素(或 <template>
)上。例如
|
v-for
与组件
本节假设你了解 组件。你可以跳过它,稍后再回来。
你可以在自定义组件上直接使用 v-for
,就像任何普通元素一样
|
在 2.2.0+ 版本中,当使用
v-for
与组件一起使用时,现在需要key
。
但是,这不会自动将任何数据传递给组件,因为组件有自己的隔离作用域。为了将迭代数据传递到组件中,我们也应该使用 props
|
不自动将 item
注入组件的原因是,这会使组件与 v-for
的工作方式紧密耦合。明确地说明数据来自哪里,使组件在其他情况下可重用。
这是一个简单的待办事项列表的完整示例
|
请注意 is="todo-item"
属性。这在 DOM 模板中是必要的,因为只有 <li>
元素在 <ul>
中有效。它与 <todo-item>
做同样的事情,但可以解决潜在的浏览器解析错误。有关详细信息,请参阅 DOM 模板解析注意事项。
|