详细问题描述
通过 v-for
循环渲染数组数据,并添加了 :key=“item.id”
,并且在子节点绑定了点击事件 @click="onItemTapped(index)"
,点击事件中接收一个索引参数,当数组的顺序发生变更后,点击事件接收到的 index 索引并不会随着更新,还是数组顺序发生变更前的索引值。
测试过 vue 原生框架是没问题的。
重现步骤
已提供测试demo,请下载附件运行查看结果。
IDE运行环境说明
[HBuilder 或 HBuilderX。如果你用其他工具开发uni-app,也需要在此说明]
HBuilderX
[IDE版本号]
2.3.2.20190921
[mac版本号]
macOS 10.14.6
uni-app运行环境说明
[运行端是h5或app或某个小程序?]
微信小程序
[运行端版本号]
微信开发者工具 稳定版 Stable Build (1.02.1907300)
[项目是cli创建的还是HBuilderX创建的?如果是cli创建的,请更新到最新版cli再试]
HBuilderX创建
[编译模式是老模板模式还是新的自定义组件模式?]
自定义组件模式
附件
[App问题请提供可重现问题的代码片段,你补充的细一点,问题就解决的快一点]
已提供测试demo,请下载附件运行查看结果。
[可重现代码片段]
<template>
<view class="content">
<block v-for="(item, index) in stores" :key="item.id">
<!-- 添加了 :key 后, 如果stores顺序变更后, onItemTapped 方法接收的 index 不会更新 -->
<view class="item" @click="onItemTapped(index)">
<text>{{item.name}}</text>
<text>-</text>
<text>{{index}}</text>
</view>
</block>
</view>
</template>
<script>
export default {
data() {
return {
stores: [],
}
},
onLoad() {
// 模拟门店数据
var stores = new Array(10).fill(0).map((_, index) => {
var item = {};
item.id = index;
item.name = `store ${index}`;
item.distance = 0;
return item;
});
this.stores = stores;
/**
* 模拟门店数据按位置距离排序
*
* 当获取到用户的位置信息后,根据距离重新排序
*/
setTimeout(() => {
var newStores = this.stores;
newStores.forEach(element => element.distance = Math.random());
newStores.sort((s1, s2) => s1.distance - s2.distance);
this.stores = newStores;
}, 5000);
},
methods: {
onItemTapped: function(index) {
// TODO: 这里接收到的 index 不可靠
const item = this.stores[index];
console.log(index, item.name);
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.item {
width: 100%;
height: 88rpx;
display: flex;
flex-direction: row;
align-items: center;
border-bottom: 1rpx solid #333333;
}
</style>