列表渲染
v-for
通过 v-for 指令渲染元素。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是数据源,而 item 则是被迭代的元素别名。
遍历数组:
遍历时可以拿到两个值,一个是 item 迭代项,index 索引。
<template>
<div>
<ul>
<li v-for="(item, index) in ['1', '2', '3']" :key="index">
{{ item }}
</li>
</ul>
</div>
</template>
使用 of 代替 in 作为分隔符,of 更接近 JavaScript 迭代数组的语法。
<template>
<div>
<ul>
<li v-for="(item, index) of ['1', '2', '3']" :key="index">
{{ item }}
</li>
</ul>
</div>
</template>
遍历对象:
遍历时可以拿到三个值 (value, key, index),value 属性值,key 属性名,index 索引。
注意:遍历对象的顺序是按属性最早创建的时间排序来。
<template>
<div>
<ul>
<li v-for="(value, key, index) in { name: '张三', gender: '男' }" :key="key">
{{ value }} - {{ key }} - {{ index }}
</li>
</ul>
</div>
</template>
key 的作用
在 Vue 中,key 是用来标识每个节点的唯一性,Vue 采用 diff 比较 新/旧 vnode 时,通过 key 来判断两个节点是否相同,从而决定是否需要重新渲染。
不设置 key 值:
在这种下面例子中,通过 v-for 指令渲染的 li 标签并没有设置 key 值。
<template>
<div>
<ul>
<li v-for="(item, index) in list">
{{ item }}
</li>
</ul>
<button @click="add">新增</button>
<button @click="del">删除</button>
</div>
</template>
<script>
export default {
data() {
return {
list: ["3", "2", "1"],
count: 3
};
},
methods: {
add() {
// 往数组前面添加数据。
this.list.unshift(++this.count);
},
del() {
// 删除数组的第一项数据。
this.list.splice(0, 1);
}
},
};
</script>
例子中点击 新增 或 删除 按钮操作的都是列表数据的第一项数据。
按道理在我每次点击 新增 或 删除 就只会在列表的第一项添加一个 li 标签。
但实际上因为没有给 li 设置 key 值作为唯一标识性,在列表数据发生改变时,会产生 新的vnode,Vue 通过 diff 对 新/旧vnode 进行比较,Vue 就会复用已有的元素,只对内容做更新。
最后会发现,在操作时理应只对一条数据做相应的处理,但实际上每次列表数据更新,所有的 li 也会更新,并且新增 或 删除 操作的都是最后一条数据。
使用
index作为key和不设置key值一样,index会随着数组变化而变化。在操作
动态元素的情况下,需要保证key的不变性。
可以打开 F12,选中 li 的结构后,点击 新增 或 删除 按钮,可以看到所有的 li 元素都发生了 闪烁,是因为 li 元素都发生了更新。
设置 key 值:
<li v-for="(item, index) in list" :key="item">
{{ item }}
</li>
设置了 key 后,打开 F12,再次操作数据,会发现只有对应的 li 标签发生了更新。
数组更新检测
Vue 对部分的数组方法进行了封装,使用封装后的方法对数组进行操作会触发响应系统,从而触发视图更新。
push()pop()shift()unshift()splice()sort()reverse()
例如,你要在数组最后一项添加内容:
<template>
<div>
{{ list }}
</div>
</template>
<script>
export default {
data() {
return {
list: ["3", "2", "1"],
};
},
mounted() {
const length = this.list.length;
this.list[length - 1] = "4";
},
};
</script>
this.list[length - 1] = 值 这种方式操作数据不会引起页面的刷新。需要使用 Vue 封装过的数组方法。
mounted() {
this.list.push("4");
},
转载自:https://juejin.cn/post/7236921385472327717