7***@qq.com
7***@qq.com
  • 发布:2022-07-19 15:34
  • 更新:2022-07-20 11:04
  • 阅读:237

【报Bug】vue3中使用v-for循环插槽编译到小程序后会有问题

分类:uni-app

产品分类: uniapp/小程序/微信

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: w10

HBuilderX类型: 正式

HBuilderX版本号: 3.4.18

第三方开发者工具版本号: 最新版

基础库版本号: 2.24.6

项目创建方式: HBuilderX

示例代码:

父组件是这样的

<template>  
        <testSlot :data="item" v-for="item in data" :key="item">  
        <template v-slot:default="scope">  
            <view @click="deleteData(scope.info)">{{ scope.info }}</view>  
        </template>  
    </testSlot>  

    <testSlot2 :data="item" v-for="item in data" :key="item"   
        @deleteData="deleteData">  
    </testSlot2>   

    <testSlot3 :data="data">  
        <template v-slot:default="scope">  
            <view @click="deleteData(scope.info)">{{ scope.info }}</view>  
        </template>  
    </testSlot3>  
</template>  

<script setup>  
        import testSlot from './testSlot.vue'  
    import testSlot2 from './testSlot2.vue'  
    import testSlot3 from './testSlot3.vue'  

    const data = ref([])  
    data.value = Array.from({ length: 30 }, (v, i) => i)  

    function deleteData(info) {  
        const index = data.value.findIndex(ele => ele === info)  
        if(index > -1)  
            data.value.splice(index, 1)  
    }  
</script>

子组件 testSlot

<template>  
    <view class="button">  
        <slot :info="data"></slot>  
    </view>  
</template>  

<script setup>  
    import { toRefs } from 'vue'  

    const props = defineProps({ data: Number })  

    const { data } = toRefs(props)  
</script>  

<style lang="stylus">  
.button  
    width: 100rpx  
    line-height: 60rpx  
    text-align: center  
    border: 1rpx solid #666  
    border-radius: 8rpx  
</style>  

子组件 testSlot2

<template>  
    <view class="button" @click="deleteData(data)">  
        {{ data }}  
    </view>  
</template>  

<script setup>  
    import { toRefs } from 'vue'  

    const props = defineProps({ data: Number })  

    const { data } = toRefs(props)  
    const emits = defineEmits(['deleteData'])  

    function deleteData (data) {  
        emits('deleteData', data)  
    }  
</script>  

<style lang="stylus">  
.button  
    width: 100rpx  
    line-height: 60rpx  
    text-align: center  
    border: 1rpx solid #666  
    border-radius: 8rpx  
</style>  

子组件 testSlot3

<template>  
    <view class="button" v-for="item in data" :key="item">  
        <slot :info="item"></slot>  
    </view>  
</template>  

<script setup>  
    import { toRefs } from 'vue'  

    const props = defineProps({ data: Array })  

    const { data } = toRefs(props)  
    const emits = defineEmits(['deleteData'])  

    function deleteData (data) {  
        emits('deleteData', data)  
    }  
</script>  

<style lang="stylus">  
.button  
    width: 100rpx  
    line-height: 60rpx  
    text-align: center  
    border: 1rpx solid #666  
    border-radius: 8rpx  
</style>  

操作步骤:

代码如上所示,使用testSlot这种作用域插槽写法删除时问题很大,使用testSlot2这种不使用插槽的写法没有问题,使用testSlot3这样写法时wx控制台会有较多警告

预期结果:

三种方式都能正常使用

实际结果:

第一种方式有很大问题,已上传视频,可以看到明显问题,尤其最后多次点击4号并没有被删除

bug描述:

今天突然发现项目在删除列表时有问题,然后写了几个dome测试发现是slot的问题,在H5没有问题,但是在小程序端会有无法删除的情况,数组元素实际已经删除但是页面没有更新

2022-07-19 15:34 负责人:无 分享
已邀请:
DCloud_UNI_WZF

DCloud_UNI_WZF

写法1删除不了是因为操作删除部分 item 后 scope.info 触发了边界,改为index 试试
写法3警告是因为微信小程序不支持多个同名插槽

  • 7***@qq.com (作者)

    我实际项目做的时候是用index做删除,同样有问题,我认为和第一种写法差不多,所以没有列出来,但是确实只是在小程序端出现问题

    <testSlot :data="item" v-for="(item, index) in data" :key="item">

    <template v-slot:default="scope">

    <view @click="deleteData(scope.info, index)">{{ scope.info }}</view>

    </template>

    </testSlot>

    2022-07-20 11:41

  • 7***@qq.com (作者)

    如果改成这样也没有问题

    <testSlot :data="item" :index="index" v-for="(item, index) in data" :key="item">

    <template v-slot:default="scope">

    <view @click="deleteData(scope.info, scope.index)">{{ scope.info }}</view>

    </template>

    </testSlot>

    2022-07-20 11:42

  • 7***@qq.com (作者)

    这个确实不算什么大问题,注意写法就可以避免

    2022-07-20 11:46

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