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)"><!-- Updated event binding -->
<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明显不对,可看附件;
附件:
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
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
微信小程序平台暂未支持多次渲染同名插槽,参考: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
名称冲突。
解决方案
-
动态生成
slot
名称: 在v-for
循环中,可以通过动态生成slot
名称来避免重复。例如,可以在slot
名称中加入循环的索引或唯一标识符。<template> <view v-for="(item, index) in list" :key="index"> <slot :name="'slot' + index"></slot> </view> </template>
这样,每个
slot
名称都是唯一的,避免了重复的问题。 -
使用
scoped slots
: 如果需要在slot
中传递数据,可以使用scoped slots
。scoped 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>
-
避免在
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>