微信小程序文章推荐:
一、为什么需要slot
在使用组件的时候可以通过自定义属性传给组件数据,组件通过properties 来接收自定义的属性,实现了组件的传值。有些情况我们封装组件的时候,有一部分视图结构是不确定的,需要外界自己定义,这时候通过自定义属性和properties 就行不通了,这就是为什么需要使用slot 的原因,使用slot ,使得组件的部分结构和样式可以由外界定义。
二、单个的slot
这里以一个弹框组件的封装为例, 弹框的内容结构和样式是不确定的,只有弹框的框样式是确定的,这个时候就可以使用slot,具体使用方式如下:
- 新建componments -> dialog 文件夹
- 选中dialog 右键新建Componpent,填写组件名称dialog 这样我们就新建好了一个组件
- 编写dialog.wxml
<!--components/dialog/dialog.wxml-->
<view class="dialog-opacity">
<view class="dialog">
<view class="header">
<text>{{ title }}</text>
<view class="close" bindtap="close">X</view>
</view>
<view class="dialog-content">
<slot></slot>
</view>
</view>
</view>
这里使用了slot 标签给内容占位,内容由外界确定
dialog.js
// components/dialog/dialog.js
Component({
/**
* 组件的属性列表
*/
properties: {
title: {
type: Number,
value: '标题'
}
},
/**
* 组件的方法列表
*/
methods: {
close () {
this.triggerEvent('close')
}
}
})
dialog.wxss
.dialog-opacity {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 9;
}
.dialog-opacity .dialog {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: calc(90% - 60rpx);
height: 300rpx;
padding: 30rpx;
border-radius: 8rpx;
background: #fff;
}
.dialog .header {
display: flex;
justify-content: space-between;
}
.dialog .dialog-content{
padding: 30rpx 0;
}
app.json 中将弹框注册为全局组件:
{
"pages": [
"pages/index/index",
],
"window": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "Weixin",
"navigationBarBackgroundColor": "#ffffff"
},
"style": "v2",
"componentFramework": "glass-easel",
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents",
"usingComponents": {
"my-dialog": "/components/dialog/dialog"
}
}
重点: "my-dialog": "/components/dialog/dialog"
index.wxml页面使用
<!--index.wxml-->
<view>
<my-dialog bind:close="close" wx:if="{{showDialog}}">
<view>第一段内容</view>
<view>第二段内容</view>
</my-dialog>
<button bindtap="open" type="primary">打开弹框</button>
</view>
在这里我们直接在my-dialog 标签之间写自定义内容,my-dialog组件中的slot 就会接收到
index.js
// index.js
Page({
data: {
showDialog: false
},
close () {
this.setData({
showDialog: false
})
},
open () {
this.setData({
showDialog: true
})
}
})
这样我们就利用slot 完成了可以自定义内容结构的弹框。
三、多个slot
有时候,我们的组件不止只有一个内容需要自定义结构,有多个内容需要自定义结构,这时候就需要使用多个slot 了。使用多个slot 在上面的单个基础上需要还需要进行3点修改
- 组件js中的options 选项中添加 multipleSlots: true
- 使用slot的时候需要在组件里面的slot标签上增加name定义一个slot的名称
- 在父组件或者页面中使用的时候通过slot属性来确定自定义的结构放在哪个slot标签的位置。
还是以上面的弹框为例,假设现在标题结构也可能不只是一段文案了,可能还有图标和文案,这些标签结构,底部可能有两个按钮或者只有一个按钮,这种情况就可以用多个slot了, 具体使用如下:
dialog.wxml
<!--components/dialog/dialog.wxml-->
<view class="dialog-opacity">
<view class="dialog">
<view class="header">
<slot name="title"></slot>
<view class="close" bindtap="close">X</view>
</view>
<view class="dialog-content">
<slot name="content"></slot>
</view>
<view class="footer">
<view><slot name="footer"></slot></view>
</view>
</view>
</view>
重点:
<slot name="title"></slot><slot name="content"></slot><slot name="footer"></slot>
dialog.js
// components/dialog/dialog.js
Component({
options: {
multipleSlots: true
},
/**
* 组件的属性列表
*/
properties: {
title: {
type: Number,
value: '标题'
}
},
/**
* 组件的方法列表
*/
methods: {
close() {
this.triggerEvent('close')
}
}
})
重点multipleSlots: true
dialog.wxss
.dialog-opacity {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 9;
}
.dialog-opacity .dialog {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: calc(90% - 60rpx);
height: 300rpx;
padding: 30rpx;
border-radius: 8rpx;
background: #fff;
}
.dialog .header {
display: flex;
justify-content: space-between;
}
.dialog .dialog-content{
padding: 30rpx 0;
}
.dialog .footer{
display: flex;
justify-content: center;
}
index.wxml
<!--index.wxml-->
<view>
<my-dialog bind:close="close" wx:if="{{showDialog}}">
<view
slot="title"
>
<image src="/assets/img/tip.png" class="title-icon"></image>
标题
</view>
<view slot="content">
<view>第一段内容</view>
<view>第二段内容</view>
</view>
<view slot="footer">
<button size="mini" bindtap="close">取消</button>
<button type="primary" size="mini" bindtap="confirm">确定</button>
</view>
</my-dialog>
<button bindtap="open" type="primary">打开弹框</button>
</view>
重点:
slot="title"slot="content"slot="footer"
index.js
// index.js
Page({
data: {
showDialog: false
},
confirm () {
console.log('confirm')
this.setData({
showDialog: false
})
},
close () {
this.setData({
showDialog: false
})
},
open () {
this.setData({
showDialog: true
})
}
})
index.wxss
.title-icon {
width: 20px;
height: 20px;
}
运行效果:
四、 总结:
本篇介绍了,单个slot 的用法,多个slot的用法,合理的利用slot 可以增强组件的可扩展性。
今天就分享到这里了,感谢收看,如果你对小程序开发感兴趣,可以关注uni-app,小程序知识储备 专栏