起因
众所周知,小程序至今还未支持 slot 显示默认值(五年啦),但是业务中这个需求还是挺普遍的,故此分享下我是怎么实现该需求的。
构建一个场景
有一个列表单项组件,当名为 icon 的 slot 有内容传入时,显示该 slot,否则显示默认的 icon。
示例代码
需要将组件的 js 中的 multipleSlots 设置为 true。
<!-- ListItem.wxml -->
<view class="list-item">
<view class="list-item__content">
<view class="list-item__left">
<view class="list-item__left-icon--slot">
<slot name="icon"></slot>
</view>
<view class="list-item__left-icon"></view>
<view>{{title}}</view>
</view>
<view class="list-item__right">
<slot></slot>
</view>
</view>
</view>
// ListItem.scss
.list-item {
.list-item__content {
.list-item__left {
&-icon--slot {
margin-right: 12rpx;
&:empty {
display: none;
}
&:not(:empty) + .list-item__left-icon {
display: none;
}
}
&-icon {
width: 40rpx;
height: 40rpx;
margin-right: 12rpx;
color: var(--color-text-disabled);
background-color: currentColor;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: 100%;
-webkit-mask-image: url('xxx.png')
}
}
}
}
总结
实现的原理解释:
- 当 slot 没有内容时,利用了
:empty
伪类选择器,隐藏.list-item__left-icon--slot
的元素。 - 当 slot 有内容时,利用了
:not
以及+
选择器,使与.list-item__left-icon--slot
紧邻且在其之后的.list-item__left-icon
的元素隐藏
不过需要注意的一点是,官方文档中 wxss 支持的选择器很有限,但是实测是大部分支持的,目前个人尝试已知不可用的选择器有 *
、~
以及属性选择器(还有一些复杂情况可能也不支持,需要大家自己尝试)。
希望这次分享对大家有一定的帮助吧。