小程序必备技巧(6)—实现类似于Vue的“默认插槽”功能

1,424 阅读3分钟

在业务开发中,我们会遇到类似于如下场景:

在有的页面中展示的标题如下:

而有的页面展示的标题如下:

而有的页面展示标题如下:

我们会考虑将标题内容封装为一个通用的标题组件:

  • 左侧的标题通过属性传入

  • 而右侧展示的内容是多形态的,有的展示为更多,有的不展示,有的可能还会展示别的内容,是可以自定义的

    • 对于是否展示右侧内容,我们可以通过传入一个boolean类型的属性来决定是否展示
    • 而对于这种可自定义的内容,我们可考虑通过插槽来实现 若对于大部分页面来说,右侧展示的内容为“更多 >”,那么我们期望达到类似于vue的“默认插槽”的效果:
  • 在不向插槽中传入内容时默认展示“更多 >”

  • 向插槽中传入内容时则展示传入的内容

那么小程序中如何实现呢?

一、小程序中的插槽特点

小程序中是支持插槽功能的,对比vue来说,小程序的插槽是不支持设置默认值的

1-1、vue中的默认插槽

在vue中,若想为插槽设置默认值,只需在标签中写入想默认展示的内容即可:

<slot>
  <span>这里是默认展示的内容</span>
</slot>

1-2、小程序中的插槽

而在小程序中,是不支持向中写入默认内容的,即使写入了内容,在页面上也不会展示出来:

尝试在封装的组件代码中写入插槽,并在插槽内写入想展示的默认内容,在使用后会发现,并没有像vue那样展示出来插槽中的默认内容:

可见小程序中是不支持“默认插槽”功能的。

那么我们如何结合小程序插槽来实现一个类似于vue“默认插槽”的功能呢?

二、在小程序中实现“默认插槽”功能

2-1、编写wxml组件代码

<view class="header">
  <view class="title">{{ title }}</view>
  <view class="right" wx:if="{{showRight}}">
    <view class="slot"><slot></slot></view>
    <view class="default">
      <text>{{ rightText }}</text>
      <image class="icon" src="/assets/images/icons/arrow-right.png" />
    </view>
  </view>
</view>

对于上述场景的header组件wxml代码如上,但此时依旧不能实现“默认插槽”功能,此时若向插槽中传入内容,则传入的内容会与默认内容一同展示出来:

可见插入的内容与“更多 >”都展示出来了,而我们想实现的是一旦插入了内容则默认内容不展示,没有插入内容则才展示默认内容的互斥效果。

我们也可以通过传入一个Boolean属性来决定展示默认内容还是插入的内容,但这还得通过额外的属性去维护,有些麻烦,有没有更优雅的方式来实现呢?

2-2、结合CSS来实现“默认插槽”效果

由此想到了,CSS3的:empty选择器来判断是否插入了内容:

.header .slot:empty + .default {
  display: flex;
}
.header .default {
  display: none;
  align-items: center;
  font-size: 28rpx;
  color: #777;
}
  • 首先,默认内容区域不展示:display:none
  • 利用:empty选择器判断.slot中内容为空时,再让其兄弟节点.default展示即可

由此,我们便在小程序中实现了类似于vue的“默认插槽”功能~