<swiper-item class="flexColumn fBlock" v-for="item,index in dataList" :key="item?.id||index">
<slot :item="item" :index="index"></slot>
</swiper-item>

- 发布:2025-08-07 14:37
- 更新:2025-08-07 16:11
- 阅读:79
产品分类: uniapp/小程序/微信
PC开发环境操作系统: Windows
PC开发环境操作系统版本号: window 10
HBuilderX版本号: 4.75
第三方开发者工具版本号: 1.06.2504010 win32-x64
基础库版本号: 3.7.8
项目创建方式: CLI
CLI版本号: 3.0.0-alpha-4070620250731001
示例代码:
操作步骤:
<swiper-item class="flexColumn fBlock" v-for="item,index in dataList" :key="item?.id||index">
<slot :item="item" :index="index"></slot>
</swiper-item>
<swiper-item class="flexColumn fBlock" v-for="item,index in dataList" :key="item?.id||index">
<slot :item="item" :index="index"></slot>
</swiper-item>
预期结果:
只编译出一个slot
只编译出一个slot
实际结果:
看版本对比,新版编译的时候特意加了默认插槽的判断,所以 编译出了两个slot,一个是具名插槽,一个是默认插槽,导致默认插槽在开发者工具里报了好多警告。
看版本对比,新版编译的时候特意加了默认插槽的判断,所以 编译出了两个slot,一个是具名插槽,一个是默认插槽,导致默认插槽在开发者工具里报了好多警告。
bug描述:
在v-for里写入默认插槽,看下面代码
<swiper-item class="flexColumn fBlock" v-for="item,index in dataList" :key="item?.id||index">
<slot :item="item" :index="index"></slot>
</swiper-item>
编译出来的结果多了个<slot></slot>导致微信开发工具报了一堆警告([Component] More than one slot named "default" are found inside a single component instance (in component "components/bSwiper/bSwiper"). The first one was accepted.),编译结果看下面代码
<swiper-item wx:for="{{a}}" wx:for-item="item" wx:key="d" class="flexColumn fBlock data-v-4d28a2b6">
<slot name="{{item.a}}"></slot>
<slot></slot>
</swiper-item>>
看了下编译的文件codegen.js。新版多了对默认插槽的判断。代码如下
if (node.tagType === compiler_core_1.ElementTypes.SLOT) {
const isEmptyDefaultSlot = node.props.some((p) => (p.type === compiler_core_1.NodeTypes.ATTRIBUTE &&
p.name === 'name' &&
p.value?.content === uni_shared_1.SLOT_DEFAULT_NAME) ||
(p.name === 'bind' &&
p.slotName ===
uni_shared_1.SLOT_DEFAULT_NAME)) && node.children.length === 0;
// 当存在 <slot name="default" :xxx="xxx"><slot> 时,在后面添加 <slot></slot>,使默认插槽生效
if (isEmptyDefaultSlot) {
genSlot(node, context);
return genSlot((0, shared_1.extend)({}, node, { props: [], children: [], loc: {} }), context);
}
return genSlot(node, context);
}
之前版本是没有isEmptyDefaultSlot 的判断的。多了这个判断后,虽然代码可以使用,但是报了好多警告。

z***@163.com (作者)
<template>
<swiper class="bSwiper" @change="change">
<swiper-item class="flexColumn fBlock" v-for="item,index in dataList" :key="item?.id||index">
<slot :item="item" :index="index"></slot>
</swiper-item>
</swiper>
</template>
<script setup lang="ts">
defineOptions({
name: "bSwiper",
options: {
virtualHost: true,
multipleSlots: true,
},
})
type DataItem = {
image_url : string;
[key:string]:any;
};
const props = defineProps({
dataList: {
type: Array as PropType<DataItem[]>,
default: () => []
},
})
const emits = defineEmits(["change"]);
//const current = ref<any>(0);
const change = (e : AnyObject) => {
emits("change", e.detail)
}
</script>
类似这样的简单封装一个Swiper组件。编译出来的就是两个slot。就是for里面有默认插槽的情况下都会出现编译出两个slot的情况。编译结果就是下面这样,多了一个<slot></slot> ,代码虽然可以使用,不过开发工具报好多警告的:
<swiper-item wx:for="{{a}}" wx:for-item="item" wx:key="d" class="flexColumn fBlock data-v-4d28a2b6">
<slot name="{{item.a}}"></slot>
<slot></slot>
</swiper-item>>
我临时把编译文件改回以前的了。
if (isEmptyDefaultSlot) {
return genSlot(node, context); //临时解决bug,提前return了,不会编译出两个slot。
return genSlot((0, shared_1.extend)({}, node, { props: [], children: [], loc: {} }), context);
}

z***@163.com (作者)
类似这样:
<bSwiper :dataList="swiperBanner">
<template v-slot="{item}">
<view class="fBlock" @tap="goto(item.links)">
<bImg noBgColor class="sImg iSwiper" :lazyLoad="false" :defaultType="999" :borderRadius="10" :src="item.litpic">
</bImg>
</view>
</template>
</bSwiper>
z***@163.com (作者)
不是单独这一个组件这样的。其他所有组件都是这样的。
2025-08-07 15:40
DCloud_UNI_JBB
回复 z***@163.com: 发下可复现demo
2025-08-07 15:43