xiaopin
xiaopin
  • 发布:2019-09-23 09:40
  • 更新:2019-09-24 16:36
  • 阅读:1138

【报Bug】v-for 添加 :key 后导致索引不更新的问题

分类:uni-app

详细问题描述

通过 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>
2019-09-23 09:40 负责人:无 分享
已邀请:
xiaopin

xiaopin (作者)

是不是不建议这么用呢,如果这样的话,只能把项目的代码都改了,不接收index索引,头大。。。

该问题目前已经被锁定, 无法添加新回复