在业务开发中,我们会遇到类似于如下场景:
在有的页面中展示的标题如下:
而有的页面展示的标题如下:
而有的页面展示标题如下:
我们会考虑将标题内容封装为一个通用的标题组件:
-
左侧的标题通过属性传入
-
而右侧展示的内容是多形态的,有的展示为更多,有的不展示,有的可能还会展示别的内容,是可以自定义的
- 对于是否展示右侧内容,我们可以通过传入一个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的“默认插槽”功能~