uni-app v-for有slot时 删除list里的元素时会报错

uni-app v-for有slot时 删除list里的元素时会报错

操作步骤:

组件代码
<template>  
    <view v-for="(item, index) in dataList" :key="item.id" >  
        <slot :data="item"></slot>  
    </view>  
</template>  

<script setup>  
    import { ref, defineModel } from 'vue';  
    const dataList =  defineModel('dataList', {type: Array, required: true})  
    console.log(dataList.value);  
</script>
父组件代码  
<template>  
    <TestA v-model:dataList="dataList">  
        <template #default={data}>  
            <input style="height: 30px; border: 1px solid #000; margin: 10px;"   />  
        </template>  
    </TestA>  
    <button @click="deleteItem()">删除</button>  
</template>  

<script setup>  
    import { ref } from 'vue';  
    import TestA from '@/components/test-a.vue'  
    const dataList = ref([{  
            id: 1,  
            name: 'a',  
        }, {  
            id: 2,  
            name: 'b',  
        }, {  
            id: 3,  
            name: 'c',  
        }  
    ])  
    function deleteItem() {  
        dataList.value.splice(0, 1)  
    }  
</script>

预期结果:

预期不报错, 且删除后变为2个input框 , 第一个里面的值是 2 , 第二个里面的值为空

实际结果:

报错, 第一个里面的值是 1 , 第二个里面的值为 2

bug描述:

<view v-for="(item, index) in dataList" :key="item.id" >
<slot :data="item"></slot>
</view>  

在微信小程序里当dataList里的元素发生删除时, 会报错  

[Component] More than one slot named "d-0" are found inside a single component instance (in component "components/test-a"). The first one was accepted.  

h5不会出现这种情况, 而且如果slot里传的如果有input , 输入的东西不会删除, 是不是底层的key出了问题  

Image

Image


更多关于uni-app v-for有slot时 删除list里的元素时会报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

更多关于uni-app v-for有slot时 删除list里的元素时会报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是因为在微信小程序环境中,v-forslot的组合使用时存在组件实例复用问题。当删除数组元素时,小程序底层会尝试复用已有的组件实例,但由于slot内容动态变化,导致slot命名冲突。

解决方案:

  1. 为外层容器添加唯一key
<view v-for="(item, index) in dataList" :key="item.id">
    <slot :data="item"></slot>
</view>
  1. 避免直接修改数组引用,使用响应式更新:
function deleteItem() {
    dataList.value = dataList.value.slice(1) // 创建新数组
    // 或者
    dataList.value.splice(0, 1)
}
  1. 如果问题依旧存在,可以强制重新渲染:
<TestA v-model:dataList="dataList" :key="dataList.length">
回到顶部