在uni-app组件的v-for里使用slot时多渲染了一个<slot></slot>导致微信开发工具报好多警告
在uni-app组件的v-for里使用slot时多渲染了一个<slot></slot>导致微信开发工具报好多警告
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Windows | window 10 | CLI |
示例代码:
<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,一个是具名插槽,一个是默认插槽,导致默认插槽在开发者工具里报了好多警告。
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>,使默认插槽生效
if (isEmptyDefaultSlot) {
genSlot(node, context);
return genSlot((0, shared_1.extend)({}, node, { props: [], children: [], loc: {} }), context);
}
return genSlot(node, context);
}
更多关于在uni-app组件的v-for里使用slot时多渲染了一个<slot></slot>导致微信开发工具报好多警告的实战教程也可以访问 https://www.itying.com/category-93-b0.html
你的完整的代码是怎么写的?
更多关于在uni-app组件的v-for里使用slot时多渲染了一个<slot></slot>导致微信开发工具报好多警告的实战教程也可以访问 https://www.itying.com/category-93-b0.html
不是单独这一个组件这样的。其他所有组件都是这样的。
回复 z***@163.com: 发下可复现demo
类似这样的简单封装一个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);
}
你外面怎么使用这个组件?isEmptyDefaultSlot 是为了解决默认插槽的显示问题,我看看怎么优化下这里
回复 DCloud_UNI_JBB: 优化了吗这里
回复 2***@qq.com: 等下一个alpha
类似这样:
<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>
临时解决方案可以参考这个帖子 https://ask.dcloud.net.cn/question/215135
这是一个已知的uni-app编译问题。在v-for循环中使用具名插槽时,编译器会额外生成一个默认插槽,导致微信开发者工具报出多个default slot的警告。
问题分析:
从你提供的编译代码可以看出,编译器在处理<slot :item="item" :index="index">时,将其编译为具名插槽<slot name="{{item.a}}"></slot>,但同时添加了一个空的默认插槽<slot></slot>,这违反了微信小程序的单slot限制。
临时解决方案:
- 使用template包装:
<swiper-item class="flexColumn fBlock" v-for="item,index in dataList" :key="item?.id||index">
<template>
<slot :item="item" :index="index"></slot>
</template>
</swiper-item>
- 避免在v-for中直接使用slot,改为在父组件中循环:
// 父组件
<b-swiper>
<swiper-item v-for="item,index in dataList" :key="item?.id||index">
<!-- 具体内容 -->
</swiper-item>
</b-swiper>

