【已解决】uniapp微信小程序具名插槽多了个-1?循环slot失效的真正原因
UniApp 微信小程序具名插槽名被添加后缀的问题
做 UniApp 小程序开发的时候踩了个坑,动态插槽名,莫名其妙被加上了 -0、-1 这样的后缀,对不上,本来我已经遇到过一次了,解决之后第二次又忘记了,今天就和大家分享下。
问题长什么样
子组件 FilterDropdown 这么写的:
<view v-for="(item, index) in items" :key="item.name">
<slot :name="item?.props" :close="close" :panelActive="activeIndex === index" />
</view>
父组件对应的插槽名是 #date_range_panel,想着应该能对上,结果编译到小程序里,插槽名变成了 date_range_panel-0。
根因
微信小程序不支持 Vue 原生的动态插槽,UniApp 编译器要把 :name="item.props" 转成小程序的 slot 属性。在 v-for 循环里转的时候,会把数组索引拼上去,就变成了 slot-date_range_panel-0。
加上 v-for + 动态插槽 + { close, panelActive } 解构这三个东西凑一起,编译器更容易抽风。
踩坑过程
第一反应是能不能手动指定 props: "date_range_panel-0",让编译器的拼接结果对上。
结果是小程序模板里变成了 <view slot="date_range_panel-0-0">,编译器拿到 props: "date_range_panel-0" 之后还会再拼一层索引,等于白搭。
怎么解决
用 expose + ref 代替解构。
不用作用域插槽传过来的 close,改成子组件用 defineExpose 暴露方法,父组件直接调。
子组件改一下:
<script setup lang="ts">
const activeIndex = ref(-1);
const close = () => {
activeIndex.value = -1;
};
defineExpose({
close,
activeIndex,
});
</script>
父组件那边:
<template #date_range_panel>
<DateRangePanel
ref="dateRangePanelRef"
@confirm="handleDateConfirm"
/>
</template>
const filterDropdownRef = ref();
filterDropdownRef.value?.close();
这样就不依赖解构了,插槽名爱加什么后缀加什么后缀,反正父组件根本不用解构拿数据。
经验之谈
微信小程序里,v-for + 动态插槽 + 作用域插槽解构这三件套能不凑一起就别凑一起。实在要用,就用 defineExpose 把方法暴露出去,别走解构那条路。
refs 在小程序里本来就好使,换这个写法心理负担也不大。
更多推荐
所有评论(0)