记录-记一次不规范使用key引发的惨案

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

前言

平时在使用v-for的时候,一般会要求传入key,有没有像我一样的小伙伴,为了省心,直接传索引index,貌似也没有遇到过什么问题,直到有一天,我遇到一个这样的需求

场景

在一个下单界面,我需要去商品列表选商品,然后在下单界面遍历显示所选商品,要求后选的排在前面,而且选好商品之后,需要在下单界面给每个商品选择发货地,发货地列表是通过商品id去接口取的,我的代码长这样:

  • 下单界面调用商品组件
// 这里每次选了商品都是从前插入:list.value = [...newList, ...list.value]
<Goods
  v-for="(item, index) in list"
  :key="index"
  :goods="item">
</Goods>
  • 商品组件内部调用发货地组件
<SendAddress
    v-model="address"
    :product-no="goods.productNo"
    placeholder="请选择发货地"
    @update:model-value="updateValue"></SendAddress>
  • 发货地组件内部获取发货地址列表
onMounted(async () => {
  getList()
})
const getList = async () => {
  const postData = {
    productInfo: props.productNo,
  }
}

上述代码运行结果是,每次获取地址用的都是最开始选的那个商品的信息,百思不得其解啊,最后说服产品,不要倒序了,问题解决

解决过程

后来在研究前进刷新后退缓存时,关注到了组件的key,详细了解后才知其中来头

重点:根据key复用或者更新,也就是key没有变化,就是复用,变化了在更新挂载,而onMounted是在挂载完成后执行,没有挂载的元素,就不会走onMounted

回到上述问题,当我们每次从前面插入数据,key的变化逻辑是这样的

结论

最开始选中的商品key从1变成了2,最近选的是0。

而0和1是本来就存在的,只会更新数据,不会重新挂载,只有最开始选的那个商品key是全新的,会重新挂载,重新走onMounted。

所以每次选择数据后,拿去获取地址列表的商品信息都是第一个的

解决以上问题,把key改成item.productNo就解决了

本文转载于:

https://juejin.cn/post/7221357811287834680

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

热门相关:仙城纪   第一神算:纨绔大小姐   致灿烂的你   网游之逆天飞扬   豪门闪婚:帝少的神秘冷妻