uni-app开发微信小程序,动态插槽名,在 uni-app 中使用动态 slot 名字

# 前言

要在 uni-app 中使用动态 slot 名字,会比较麻烦,因为:在 MP-WEIXIN、APP-PLUS 都会有坑。

# H5 和 小程序端

我们先说比较常用的 H5 和 MP-WEIXIN 好了:

定义:

<!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
<!-- #ifdef H5 -->
<slot :name="`tab:${item.key}`"></slot>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN-->
<slot name="tab:{
   
   {item.key}}"></slot>
<!-- #endif -->

使用 slot:

<view>
  <!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
  <!-- #ifdef H5 -->
  <template v-for="item in list" :slot="`tab:${item.id}`">
    <post-list :key="item.id" />
  </template>
  <!-- #endif -->

  <!-- #ifdef MP-WEIXIN-->
  <template v-for="item in lits" slot="tab:professional:{
   
   {item.id}}">
    <post-list :key="item.id" />
  </template>
  <!-- #endif  -->
</view>

# APP 端

如果还要兼容 APP 端(vue 文件),则情况会变得稍微复杂一点,以上两种情况都不适用,先说结论:

  1. 不支持拿 data 的数据用于拼接动态 slot 名字
  2. 在 v-for 中要根据当前项的字段来拼接 slot 名字,则要将 key 指向item 本身(不推荐
  3. 能拿 v-for 的 index 来拼接 slot 名字(推荐
# 解决方案

也即,如果是上面的例子,需要改写为如下::

<swiper-item v-for="(item, index) in tabs" :key="item.id" class="swiper-item">
  <!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
  <!-- #ifdef H5 || APP-PLUS -->
  <slot :name="`tab:${index}`"></slot>
  <!-- #endif -->
  <!-- #ifdef MP-WEIXIN-->
  <slot name="tab:{
   
   {index}}"></slot>
  <!-- #endif -->
</swiper-item>

使用的时候:

<tab-swiper
  ref="tabSwiper"
  :tabs="list"
  :current.sync="current"
  :swiper-current.sync="swiperCurrent"
>
  <!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
  <!-- #ifndef H5 || APP-PLUS -->
  <template v-for="(item, index) in list" :slot="`tab:${index}`">
    <post-list :key="item.id" :stagger="index % 2 !== 0" />
  </template>
  <!-- #endif -->

  <!-- #ifdef MP-WEIXIN-->
  <template v-for="(item, index) in list" slot="tab:{
   
   {item.id}}">
    <post-list :key="item.id" :stagger="index % 2 !== 0" />
  </template>
  <!-- #endif  -->
</tab-swiper>
# 排查问题

下面开始排查问题,首先我们用以下代码测试用 data 的数据来作为 slot 名字:

<template>
  <view>
    testing dynamic slot
    <slot :name="key"></slot>
    <view :class="key">
      test key value
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      key: 'slot-1',
    }
  },
}
</script>

可以看到,即便同样使用了 key 作为属性,但它们编译后的代码是不一样的,slot 节点直接使用_vm._key,而 view 节点变成了_vm._$(2,'c'),由此也推断出 uni-app 内部并没有对 slot 的name属性做额外处理,其实如果打印_vm.key的值, 会发现是空的:

所以结论一:不支持拿 data 的数据用于拼接动态 slot 名字。

但直接拿 data 数据来拼接 slot 名字的情况比较少,更多时候是在 v-for 循环内部,所以我们再拿以下代码做测试:

<template>
  <view>
    testing dynamic slot
    <view v-for="item in list" :key="item.id">
      {
   
   { item.name }}
      <slot :name="`tab:${item.id}`"></slot>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      list: [
        {
          id: 'a',
          name: 'item-a',
        },
        {
          id: 'b',
          name: 'item-b',
        },
        {
          id: 'c',
          name: 'item-c',
        },
      ],
    }
  },
}
</script>

不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值。

猜你喜欢

转载自blog.csdn.net/weixin_45395283/article/details/132832252
今日推荐