项目中遇到过的问题
前提
1. 咱们先来看一个需求
一个排行榜,有日榜和总榜,通过点击Tab切换列表数据,显示的数据内容及样式都是一样的,每一条数据都有个点赞按钮。
2. 根据需求,我们做一个简单的项目规划
为方便管理并优雅的实现需求,我们最好写一个组件(item)来显示每一条数据。
补充一点:因为一个项目中用到Tab的地方比较多,如果风格相似,我们可以将Tab也写成一个组件。
3. 开发阶段
我们定义一个存放数据的对象
data() {
return {
rankLists: {
0: [], // 日榜
1: [] // 总榜
}
}
},
computed: {
// 这里我们获取到了对应Tab的数据
rankList() {
return this.rankLists[this.index]; // 在我们点击tab的时候this.index会接收到一个number;
}
}
我是分割线-----------------------------------------------------------------💯
接下来我们进行DOM渲染
1. 第一种方式,让key的值为下标index。
<template v-for="(item, index) in rankList">
<item :key="index"
:item="item" />
<template/>
当我给日榜的第一个用户点赞,然后切换Tab,这么做会发生什么呢?
你会发现,总榜的第一个用户也是已点赞状态,如果是这样的话显然是有问题的。
那么是什么原因导致的问题呢。
我们先分析问题,在我给日榜第一个用户点赞,总榜相同位置的数据也变成已点赞状态了,那我在试试给其他用户点赞试试,不难发现,只要给其中一个榜单的点赞,另一个榜单的相同位置也会变成已点赞状态。
2. 第二种方式,让key的值为user_id(唯一标识)。
<template v-for="item in rankList">
<item :key="item.user_id"
:item="item" />
<template/>
用这种方式重复上面的操作。我们发现没有出现那样的问题。
我是分割线-----------------------------------------------------------------💯
总结一下
当我们用下标index作为key的值的时候,切换tab,新的列表会复用之前列表相同下标的组件,于是就造成第一种方式发生的问题。而当我们使用第二种方式,每一个key的值都是唯一的,这个时候切换Tab,页面更新会先去找是否有可复用的组件(去找相同的key),如果没有就会删除 / 新建组件,所以第二种方式没有问题。
我们再来说说性能,当页面更新找不到可复用组件的时候,就会涉及到组件的删除 / 新建,这种方式不可避免存在性能上的开销,但这样的性能开销用户几乎是感觉不到的。
我是底部
一些开发过程中的经验总结,如果对你有帮助,那真是一件很棒的事,如果内容有什么问题或建议,欢迎在下方留言。😀 😀 😀