uni-app v-for里的slot编译有问题

uni-app v-for里的slot编译有问题

开发环境 版本号 项目创建方式
Windows x64 HBuilderX

操作步骤:

  • 直接编译

预期结果:

<view wx:for="{{a}}" wx:for-item="item" wx:key="c"><slot name="{{item.a}}"></slot></view>

实际结果:

<view wx:for="{{a}}" wx:for-item="item" wx:key="c"><slot name="{{item.a}}"></slot><slot></slot></view>

bug描述:

<view v-for="(item, index) in dataList" :key="item.id" >
<slot :data="item"></slot>
</view> 
编译成微信小程序多了一个<slot></slot> 

<view wx:for="{{a}}" wx:for-item="item" wx:key="c"><slot name="{{item.a}}"></slot><slot></slot></view> 

导致报错  
More than one slot named "" are found inside a single component instance (in component "components/test-slot").

更多关于uni-app v-for里的slot编译有问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

17 回复

我咋记得有个类似的问题

更多关于uni-app v-for里的slot编译有问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html


好像都是一个问题, 现在还没修复

编译过的微信小程序删除一下多余的<slot></slot>就不警告了, 但是太费劲了, 写插件也不能让用户都手动删一下

回复 2***@qq.com: view 改成template 标签试试

回复 jgj_app: 也不行

回复 2***@qq.com: 那就慢慢等他们修复

回复 2***@qq.com: 私信你了

等后续alpha发版会修复

回复 筝筝日上: 看下im

啥解决方案

临时解决方案
找到 HX根目录/Contents/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-mp-compiler/dist/template/codegen.js
搜索 function genNode(node, context)
在上面添加以下代码
function isInVFor(node) {
while (node) {
if ((0, vFor_1.isForElementNode)(node)) {
return true;
}
node = node.parent;
}
return false;
} 搜索 const isVIfSlot = (0, vIf_1.isIfElementNode)(node)
在上面添加
if (isInVFor(node)) {
return genSlot(node, context);
} 找到 HX根目录/Contents/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-mp-compiler/dist/transform.js
搜索 context.parent = parent;
在上面添加 child.parent = parent;

好的, 期待下个版本, 这个只能解决个人的, 做成插件的话, 影响的用户有点多

回复 筝筝日上: 后续发版会在评论区回复

这是一个已知的uni-app编译问题。在v-for循环中使用具名slot时,编译器会错误地生成一个额外的默认slot。

临时解决方案:

  1. 避免在v-for中直接使用具名slot
  2. 改用作用域slot:
<view v-for="(item, index) in dataList" :key="item.id">
  <slot :data="item"></slot>
</view>
  1. 或者将slot内容封装为子组件:
<view v-for="(item, index) in dataList" :key="item.id">
  <child-component :data="item"></child-component>
</view>
回到顶部