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

Image Image

信息类别 内容
产品分类 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

4 回复

感谢反馈,接下里我将尝试验证并修复该bug

更多关于uni-app vue3 动态拼接slot,h5模式正常,小程序报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html


复现了吗 会修复吗

回复 5***@qq.com: 复现了,感谢您的反馈,已加分。现正排查问题并尝试修复

uni-app 中使用 Vue 3 时,动态拼接 slotH5 模式下正常工作,但在小程序模式下报错,这通常是因为小程序平台对模板解析的限制。小程序平台(如微信小程序)在模板解析时对动态内容的支持有限,尤其是在 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>
回到顶部