uni-app vue3 动态拼接slot,h5模式正常,小程序报错
uni-app vue3 动态拼接slot,h5模式正常,小程序报错
示例代码:
<template>
<view class="wrapper">
<demo :list="list">
<template v-for="(item,index) in list" v-slot:[`tab${index}`]> 11111111111111 </template>
</demo>
</view>
</template>
<script setup lang="ts">
import demo from '../../compontents/demo.vue';
import { ref } from 'vue';
const list = ref([
{
key: 'key1',
value: 'value1',
},
{
key: 'key2',
value: 'value2',
},
{
key: 'key3',
value: 'value3',
},
{
key: 'key4',
value: 'value4',
},
{
key: 'key5',
value: 'value5',
},
]);
</script>
<style scoped>
.wrapper {
padding: 200rpx;
font-size: 32rpx;
}
</style>
组件
<template>
<view v-for="(item, index) in list" :key="index">
<slot :name="'tab'+index">{{ item }}</slot>
</view>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue';
export default defineComponent({
props: {
list: {
type: Array as PropType<any[]>,
default: () => [],
},
},
setup() {
return {};
},
});
</script>
<style scoped></style>
操作步骤:
h5运行正常、小程序运行报错
预期结果:
小程序正常渲染slot内容
实际结果:
报错ReferenceError: index is not defined
bug描述:
v-for动态slot 拼接name
图一 h5运行正常,图二 小程序运行后报错 ReferenceError: index is not defined

| 信息类别 | 内容 |
|---|---|
| 产品分类 | uniapp/小程序/微信 |
| PC开发环境操作系统 | Mac |
| PC开发环境操作系统版本号 | macos14.2 |
| HBuilderX类型 | 正式 |
| HBuilderX版本号 | 3.99 |
| 第三方开发者工具版本号 | 最新 |
| 基础库版本号 | v3.3.1 (2024-01-03) |
| 项目创建方式 | HBuilderX |
更多关于uni-app vue3 动态拼接slot,h5模式正常,小程序报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html
感谢反馈,接下里我将尝试验证并修复该bug
更多关于uni-app vue3 动态拼接slot,h5模式正常,小程序报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html
回复 5***@qq.com: 复现了,感谢您的反馈,已加分。现正排查问题并尝试修复
在 uni-app 中使用 Vue 3 时,动态拼接 slot 在 H5 模式下正常工作,但在小程序模式下报错,这通常是因为小程序平台对模板解析的限制。小程序平台(如微信小程序)在模板解析时对动态内容的支持有限,尤其是在 slot 的动态拼接上。
问题分析
小程序平台的模板解析机制与 H5 不同,它不支持像 H5 那样灵活地动态拼接 slot 内容。因此,当你在 Vue 3 中动态生成 slot 内容时,小程序可能无法正确解析。
解决方案
以下是一些可能的解决方案:
1. 使用条件渲染替代动态 slot
如果可能,尽量避免动态拼接 slot,而是使用条件渲染来显示不同的内容。例如:
<template>
<component>
<template v-if="isSlotA">
<slot name="slotA"></slot>
</template>
<template v-else>
<slot name="slotB"></slot>
</template>
</component>
</template>
<script setup>
import { ref } from 'vue';
const isSlotA = ref(true);
</script>
2. 使用 scoped slots
如果动态内容较为复杂,可以考虑使用 scoped slots,将动态内容的生成逻辑交给父组件处理:
<template>
<component v-slot="{ data }">
<slot :name="data.slotName"></slot>
</component>
</template>
<script setup>
import { ref } from 'vue';
const data = ref({
slotName: 'slotA'
});
</script>
3. 使用 v-for 动态生成 slot
如果动态内容是基于列表的,可以使用 v-for 动态生成 slot:
<template>
<component>
<template v-for="(item, index) in items" :key="index">
<slot :name="item.slotName"></slot>
</template>
</component>
</template>
<script setup>
import { ref } from 'vue';
const items = ref([
{ slotName: 'slotA' },
{ slotName: 'slotB' }
]);
</script>
4. 使用 render 函数
如果以上方法都无法满足需求,可以考虑使用 render 函数来手动生成 slot 内容。render 函数在小程序平台上有更好的兼容性:
<script setup>
import { h } from 'vue';
const renderSlot = () => {
return h('div', { slot: 'dynamicSlot' }, 'Dynamic Slot Content');
};
</script>
<template>
<component>
<template #dynamicSlot>
{{ renderSlot() }}
</template>
</component>
</template>


