1️⃣ v-for 的使用
我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
1. 在 v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。
<template>
<div id="app">
<h1 v-for="(item, index) in arr" :key="item">{{ item }}{{ index }}</h1>
</div>
</template>
<script>
export default {
data() {
return {
arr: ["A", "B", "C"],
};
},
};
</script>
1️⃣ v-for 里使用对象
v-for 中使用对象和使用数组用法类似
1. 使用对象时:v-for 的第一个参数是对象 value,第二个参数是对象 key
2. 在遍历对象时,会按 Object.keys() 的结果遍历
<template>
<div id="app">
<h1 v-for="(item, index) in obj" :key="item">
<p>item: {{ item }}</p>
<p>index: {{ index }}</p>
</h1>
</div>
</template>
<script>
export default {
data() {
return {
obj: {
a: "aaa",
b: "bbb",
c: "ccc",
},
};
},
};
</script>
1️⃣ 维护状态
Vue 更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处每个元素:
1. 在"就地复用"策略中,点击按钮,输入框不随文本一起改变,是因为输入框没有与数据绑定,所以 vuejs 默认使用已经渲染的 dom,然而文本是与数据绑定的,所以文本被重新渲染。这种处理方式在 vue 中是默认的列表渲染策略,因为高效。
2. 这个默认的模式是高效的,但是在更多的时候,我们并不需要这样去处理,所以,为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,我们需要为每项提供一个唯一key 特性,Vue 会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
<template>
<div id="app">
<h1 v-for="(item, index) in obj" :key="item">
<p>item: {{ item }}</p>
<p>index: {{ index }}</p>
</h1>
</div>
</template>
<script>
export default {
data() {
return {
obj: {
a: "aaa",
b: "bbb",
c: "ccc",
},
};
},
};
</script>
2️⃣ key 的使用
预期:number | string | boolean (2.4.2 新增) | symbol (2.5.12 新增)
有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。
<template>
<div id="app">
<!-- 最常见的用例是结合 v-for: ( :key 使用数据携带的 id ) -->
<ul>
<li v-for="item in items" :key="item.id">...</li>
</ul>
</div>
</template>
1️⃣ 数组更新检测
2️⃣ 变更方法
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括
1. push()
2. pop()
3. shift()
4. unshift()
5. splice()
6. sort()
7. reverse()
2️⃣ 替换数组
变更方法,顾名思义,会变更调用了这些方法的原始数组。相比之下,也有非变更方法,例如 filter()、concat() 和 slice()。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。
2️⃣ 注意事项
由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。深入响应式原理中有相关的讨论。
1️⃣ 显示过滤/排序后的结果
有时,我们想要显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。
<template>
<div id="app">
<li v-for="n in evenNumbers" :key="n">{{ n }}</li>
</div>
</template>
<script>
export default {
data() {
return {
numbers: [1, 2, 3, 4, 5],
};
},
computed: {
evenNumbers: function() {
return this.numbers.filter(function(number) {
return number % 2 === 0;
});
},
},
};
</script>
1️⃣ v-for 里使用 number
v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数。
<template>
<div id="app">
<!-- 1 2 3 4 5 6 7 8 9 10 -->
<h1 v-for="i in 10" :key="i">{{ i }}</h1>
</div>
</template>
<script>
export default {
data() {
return {};
},
};
</script>
1️⃣ 在 上使用 v-for类似于 v-if,你也可以利用带有 v-for 的 来循环渲染一段包含多个元素的内容。比如:
<template>
<div id="app">
<template v-for="item in items">
<p :key="item">template 使用 v-for</p>
<span :key="item">{{ item }}</span>
</template>
</div>
</template>
<script>
export default {
data() {
return {
items: [1, 2, 3, 4, 5],
};
},
};
</script>
1️⃣ v-for 与 v-if 一同使用
永远不要把 v-if 和 v-for 同时用在同一个元素上
当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。
1️⃣ 在组件上使用 v-for
在自定义组件上,你可以像在任何普通元素上一样使用 v-for。
<template>
<div id="app">
<my-component v-for="item in items" :key="item.id"></my-component>
</div>
</template>
2.2.0+ 的版本里,当在组件上使用 v-for 时,key 现在是必须的。
然而,任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要使用 prop:
<template>
<div id="app">
<my-component v-for="(item, index) in items" v-bind:item="item" v-bind:index="index" v-bind:key="item.id">
</my-component>
</div>
</template>
<template>
<div id="app">
<template v-for="item in items">
<p :key="item">template 使用 v-for</p>
<span :key="item">{{ item }}</span>
</template>
</div>
</template>
<script>
export default {
data() {
return {
items: [1, 2, 3, 4, 5],
};
},
};
</script>
1️⃣ v-for 与 v-if 一同使用
永远不要把 v-if 和 v-for 同时用在同一个元素上
当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。
1️⃣ 在组件上使用 v-for
在自定义组件上,你可以像在任何普通元素上一样使用 v-for。
<template>
<div id="app">
<my-component v-for="item in items" :key="item.id"></my-component>
</div>
</template>
2.2.0+ 的版本里,当在组件上使用 v-for 时,key 现在是必须的。
然而,任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要使用 prop:
<template>
<div id="app">
<my-component v-for="(item, index) in items" v-bind:item="item" v-bind:index="index" v-bind:key="item.id">
</my-component>
</div>
</template>