uni-app 对使用v-for循环嵌套slot的组件进行二次封装时 微信开发者工具报同名称的slot重复bug

uni-app 对使用v-for循环嵌套slot的组件进行二次封装时 微信开发者工具报同名称的slot重复bug

示例代码:

使用v-for循环的slot相关组件hui-list.vue

<template>  
    <template v-if="props.options.length">  
        <hui-list-row :round="props.round">  
            <hui-list-cell v-for="(item, index) in props.options"  
                           :key="item.title"  
                           :borderColor="props.borderColor"  
                           :borderLeft="props.borderLeft"  
                           :borderRight="props.borderRight"  
                           :iconPrefix="props.iconPrefix"  
                           :leftIconColor="item.leftIcon?.color || props.leftIcon.color"  
                           :leftIconName="item.leftIcon?.name || props.leftIcon.name"  
                           :leftIconSize="item.leftIcon?.size || props.leftIcon.size"  
                           :rightIconColor="item.rightIcon?.color || props.rightIcon.color"  
                           :rightIconName="item.rightIcon?.name || props.rightIcon.name"  
                           :rightIconSize="item.rightIcon?.size || props.rightIcon.size"  
                           :showBorder="props.showBorder && props.options.length - 1 != index "  
                           @click="()=>$emit('click', item)">&lt;!-- Updated event binding --&gt;
                <template v-slot:title>  
                    <slot name="title" :props="item"/>  
                </template>  
                <template v-slot:explain>  
                    <slot name="explain" :props="item"/>  
                </template>  
            </hui-list-cell>  
        </hui-list-row>  
    </template>  
</template>

二次封装后的组件hui-dropdown-list.vue

<template>  
    <view class="hui-dropdown-list" :style="listStyle">  
        <view class="hui-dropdown-list-header">  
            <view>  
                <slot name="title"/>  
            </view>  
            <hui-icon :color="props.headerIcon.color" :name="props.headerIcon.name" :prefix="props.iconPrefix"  
                      :size="props.headerIcon.size"/>  
        </view>  
        <view class="hui-dropdown-list-body">  
            <hui-list :borderColor="props.borderColor"  
                      :borderLeft="props.borderLeft"  
                      :borderRight="props.borderRight"  
                      :iconPrefix="props.iconPrefix"  
                      :leftIconColor="props.leftIcon.color"  
                      :leftIconName="props.leftIcon.name"  
                      :leftIconSize="props.leftIcon.size"  
                      :options="props.options"  
                      :rightIconColor="props.rightIcon.color"  
                      :rightIconName="props.rightIcon.name"  
                      :rightIconSize="props.rightIcon.size"  
                      :round="props.listRound"  
                      :showBorder="props.showBorder"  
                      @click="onItemClick"/>  
                <template v-slot:title="{ props }">  
                    <slot name="cellTitle" :props="props"/>  
                </template>  
                <template v-slot:explain="{ props }">  
                    <slot name="cellExplain" :props="props"/>  
                </template>  
            </hui-list>  
        </view>  
    </view>  
</template>

操作步骤:

创建一个组件使用v-for循环嵌套slot,再创建一个组件对该组件进行二次封装,封装时使用同样的slot暴露出v-for循环嵌套的slot

预期结果:

预期结果不提示该错误,数据可以正常显示。未测试其他小程序是否有该问题,希望h5、app、各小程序都可正常使用

实际结果:

实际结果不提示该错误,数据可以正常显示。未测试其他小程序是否有该问题,希望h5、app、各小程序都可正常使用

bug描述:

v-for循环slot微信开发者工具报:[Component] More than one slot named "cellTitle" are found inside a single component instance (in component "hornetUI/components/hui-dropdown-list"). 该组件是经由一个v-for组件二次封装造成的bug,编译出的slot明显不对,可看附件;

附件:

Image Image

开发环境 版本号 项目创建方式
Windows Windows 10 HBuilderX
HBuilderX 4.14
第三方开发者工具 RC 1.06.2402021
基础库 3.4.1

更多关于uni-app 对使用v-for循环嵌套slot的组件进行二次封装时 微信开发者工具报同名称的slot重复bug的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

微信小程序平台暂未支持多次渲染同名插槽,参考:https://github.com/dcloudio/uni-app/issues/4652

更多关于uni-app 对使用v-for循环嵌套slot的组件进行二次封装时 微信开发者工具报同名称的slot重复bug的实战教程也可以访问 https://www.itying.com/category-93-b0.html


什么时候可以支持,不止微信小程序,其他小程序也有类似的问题

回复 7***@qq.com: 您好,这个问题现在解决了吗,可能是我的写法有问题,我今天遇到了,在微信小程序端确实在报这个

在使用 uni-app 进行组件封装时,如果在 v-for 循环中嵌套 slot,并且在微信开发者工具中遇到 同名称的slot重复 的报错,通常是因为在循环中多次定义了相同名称的 slot,这会导致 slot 名称冲突。

解决方案

  1. 动态生成 slot 名称: 在 v-for 循环中,可以通过动态生成 slot 名称来避免重复。例如,可以在 slot 名称中加入循环的索引或唯一标识符。

    <template>
      <view v-for="(item, index) in list" :key="index">
        <slot :name="'slot' + index"></slot>
      </view>
    </template>
    

    这样,每个 slot 名称都是唯一的,避免了重复的问题。

  2. 使用 scoped slots: 如果需要在 slot 中传递数据,可以使用 scoped slotsscoped slots 允许你在父组件中访问子组件的数据,而不需要为每个 slot 单独命名。

    <template>
      <view v-for="(item, index) in list" :key="index">
        <slot :item="item"></slot>
      </view>
    </template>
    

    在父组件中使用时:

    <template>
      <my-component>
        <template v-slot:default="{ item }">
          <view>{{ item }}</view>
        </template>
      </my-component>
    </template>
    
  3. 避免在 v-for 中使用 slot: 如果可能的话,尽量避免在 v-for 中直接使用 slot,而是将 slot 放在 v-for 的外部。这样可以在 v-for 循环中渲染不同的内容,而不需要为每个循环项都定义一个 slot

    <template>
      <slot></slot>
      <view v-for="(item, index) in list" :key="index">
        {{ item }}
      </view>
    </template>
    

示例

以下是一个完整的示例,展示了如何动态生成 slot 名称来避免重复:

<template>
  <view>
    <view v-for="(item, index) in list" :key="index">
      <slot :name="'slot' + index"></slot>
    </view>
  </view>
</template>

<script>
export default {
  props: {
    list: {
      type: Array,
      default: () => []
    }
  }
}
</script>

在父组件中使用时:

<template>
  <my-component :list="['A', 'B', 'C']">
    <template v-slot:slot0>
      <view>Slot 0 Content</view>
    </template>
    <template v-slot:slot1>
      <view>Slot 1 Content</view>
    </template>
    <template v-slot:slot2>
      <view>Slot 2 Content</view>
    </template>
  </my-component>
</template>
回到顶部