小程序模态框封装
写在前面
好久没更新啦~~最近确实有点懒了,上完班都不想写东西,小小检讨一下。最近在工作过程中涉及到了小程序的开发需求,在经过一段时间的“艰苦奋斗”后,尝试封装了模态框组件,详情如下:
基本使用
-
第一种方法:
- 在json文件中对组件进行引用
"f-dialog": "/components/modelDialog/modelDialog"
- 在全局对象中方法导入:
wx.fang.showDialog({ type:"alert", title:"标题", content:"这个是提示框" , success: (res) => { if (res.confirm) { console.log('用户点击确定') } else if (res.cancel) { console.log('用户点击取消') } } })
- 在使用的时候要在页面上使用这个组件
<f-dialog></f-dialog>
-
第二种方法
在json引入组件后直接写入组件
<f-dialog showModel="{{showModel}}" type="confirm" title="你好" title-color="yellow" show-title="{{true}}" content="456789" content-color="blue" confirm-text="yes" confirm-color="red" cancel-text="no" cancel-color="blue" locked="{{true}}" bind:fangconfirm="onClickConfirm" bind:fangcancel="onClickCancel" ></f-dialog>
基本功能
属性 | 功能 | 默认值 |
---|---|---|
showModel | 是否显示模态框 | true |
title | 标题内容 | 标题 |
content | 主体内容 | Dialog |
confirmText | 确认文字 | 确定 |
confirmColor | 确认文字颜色 | #48A0DC |
cancelText | 取消文字 | 取消 |
cancelColor | 取消文字颜色 | #000 |
locked | 锁定蒙版 | true |
titleColor | 标题颜色 | #000 |
showTitle | 显示标题 | true |
type | 模态框类型 | confirm/alert |
contentColor | 主体内容字体颜色 | rgba(89,108,142,1) |
外部样式类
外部样式类名 | 说明 |
---|---|
f-class | 设置dialog的整体样式 |
f-mask | 设置mask的样式 |
f-title | 设置标题的样式 |
f-msg | 设置文本的样式 |
f-cancel-class | 设置取消按钮的样式 |
f-confirm-class | 设置确认按钮的样式 |
模态框事件
事件名称 | 说明 | 返回值 |
---|---|---|
bind:fangConfirm | 当点击确定时触发的事件 | confirm |
bind:fangCancel | 当点击取消时触发的事件 | cancel |
bind:fangMask | 当点击模板的时候触发的事件 | mask |
设置子节点
我们在使用的组件的时候,可以根据使用场景,自由的在遮罩层组件内插入 image
、 view
、 text
等子节点,当然,你也可以在其中插入 自定义组件
。 (默认会居中显示在文本模块)
例如:
<f-dialog>
<image class="abc" src="../xxx/xxx.png"></image>
</f-dialog>
源码:
本着对大家负责的态度,上源码交流学习
WXML
<!--components/modleDialog/modelDialog.wxml-->
<view class="dialog_container f-class " wx:if="{{isShow}}">
<!-- 蒙版 -->
<view
class="mask f-mask"
bindtap="clickMask"
data-status="{{locked}}"
catchtouchmove="move"
></view>
<view class="dialog_content" animation="{{animationData}}">
<view
class="dialog_content_title f-title"
style="color:{{titleColor}}"
wx:if="{{showTitle}}"
>{{title}}</view>
<view class="dialog_content_msg f-msg" style="color: {{contentColor}}">
<slot></slot>
{{content}}
</view>
<view class="dialog_content_btn">
<view
class="dialog_content_cancle f-cancel-class"
bindtap="onClickCancel"
style="color: {{cancelColor}}"
wx:if="{{judgeType}}"
>{{cancelText}}</view>
<view
class="dialog_content_confirm f-confirm-class"
bindtap="onClickConfirm"
style="color: {{confirmColor}}"
>{{confirmText}}</view>
</view>
</view>
</view>
JS
// components/modleDialog/modelDialog.js
Component({
/**
* 组件的属性列表
*/
externalClasses: ['f-class', 'f-mask','f-title','f-msg','f-cancel-class','f-confirm-class'],
properties: {
showModel: {
type: Boolean,
value: true // 默认打开弹窗
},
title: {
type: String,
value: '标题'
},
content: {
type: String,
value: 'Dialog'
},
confirmText: {
type: String,
value: '确定'
},
confirmColor: {
type: String,
value: '#48A0DC'
},
cancelText: {
type: String,
value: '取消'
},
cancelColor: {
type: String,
value: '#000'
},
locked: {
type: Boolean,
value: true // 锁定蒙版,点击后无反应
},
titleColor: {
type: String,
value: '#000'
},
showTitle: {
type: Boolean,
value: true
},
type: {
type: String,
value: 'confirm'
},
contentColor: {
type: String,
value: 'rgba(89,108,142,1)'
}
},
/**
* 组件的初始数据
*/
data: {
judgeType: true,
success: null,
fail: null
},
observers: {
'showModel': function(showModel) {
if (showModel) {
this._showOrCloseDialog("open")
} else {
this._showOrCloseDialog("close")
}
}
},
/**
* 组件的生命周期
*/
lifetimes:{
attached: function() {
if(this.properties.showModel) {
this._showOrCloseDialog("open")
}
this.initDialog()
// 在组件实例进入页面节点树时执行
if (this.data.type == 'alert') {
this.data.judgeType = false
this.setData({
judgeType: this.data.judgeType
})
} else if (this.data.type == 'confirm') {
this.data.judgeType = true
this.setData({
judgeType: this.data.judgeType
})
} else {
return
}
},
},
/**
* 组件的方法列表
*/
methods: {
initDialog() {
wx.fang = wx.fang || {}
wx.fang.showDialog = (options) => {
const {
type = 'alert',
title = '123',
showTitle = true,
titleColor= '#45526b',
content = '',
locked = true,
confirmText = '确定',
contentColor = 'rgba(89,108,142,1)',
cancelColor = '#45526b',
cancelText = '取消',
confirmColor = '#3683d6',
success = null,
fail = null,
} = options;
this.setData({
type,
title,
showTitle,
content,
titleColor,
locked,
confirmText,
cancelColor,
cancelText,
confirmColor,
contentColor,
showModel: true,
fail,
success
});
return this;
}
},
/**
* 点击取消的事件
*/
onClickCancel(e) {
const {
success
} = this.data;
success && success({
confirm: false,
cancel: true,
errMsg: 'showDialog: success'
});
let detail = 'cancel'
this.triggerEvent('fangCancel',detail)
},
/***
* 点击确定的事件
*/
onClickConfirm(e) {
const {
success
} = this.data;
let detail = 'confirm'
success && success({
confirm: true,
cancel: false,
errMsg: 'showDialog: success'
});
this.triggerEvent('fangConfirm',detail)
},
/**
* 点击蒙版事件
*/
clickMask(e) {
let detail = 'mask'
if(!this.data.locked) {
this.data.showModel = false
this.setData({
showModel: this.data.showModel
})
}
this.triggerEvent('fangMask',detail)
},
/**
* 禁止背景滑动事件
*/
move() {},
/**
* 动画函数
*/
_showOrCloseDialog: function(currentStatu) {
var that = this;
/* 动画部分 */
var animation = wx.createAnimation({
duration: 200, //动画时长
timingFunction: "linear", //线性
delay: 0 //0则不延迟
});
this.animation = animation;
// 执行第一组动画
animation.opacity(0).rotateX(-100).step();
// 导出动画对象赋给数据对象储存
that.setData({
animationData: animation.export()
})
// 设置定时器到指定时候后,执行第二组动画
setTimeout(function() {
// 执行第二组动画
animation.opacity(1).rotateX(0).step();
// 给数据对象储存的第一组动画,更替为执行完第二组动画的动画对象
that.setData({
animationData: animation
})
//关闭
if (currentStatu == "close") {
that.setData({
isShow: false
});
}
}.bind(this), 200)
// 显示
if (currentStatu == "open") {
that.setData({
isShow: true
});
}
}
}
})
WXSS
/* components/modleDialog/modelDialog.wxss */
.mask {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background:rgba(0,0,0,0.6);
z-index: 1000;
}
.dialog_content {
position: fixed;
top: 35%;
left: 50%;
margin-left: -275rpx;
display: flex;
flex-direction: column;
align-items: center;
width: 550rpx;
background-color: #fff;
z-index: 1999;
border-radius: 15rpx;
}
.dialog_content_title {
display: flex;
align-items: center;
justify-content: center;
height: 50rpx;
padding-top: 25rpx;
font-size: 35rpx;
font-weight: 700;
font-family:PingFangSC-Regular;
}
.dialog_content_msg {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 50rpx 10rpx 50rpx 10rpx;
overflow: hidden;
white-space: normal;
word-break: break-all;
font-family:PingFangSC-Regular;
}
.dialog_content_btn {
width: 100%;
height: 80rpx;
display: flex;
justify-content: space-between;
align-items: center;
border-top: 2rpx solid #ccc;
font-family:PingFangSC-Regular;
}
.dialog_content_cancle {
display: flex;
flex: 1;
align-items: center;
justify-content: center;
height: 100%;
border-bottom-left-radius: 15rpx;
}
.dialog_content_confirm {
height: 100%;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
color: #48A0DC;
border-left: 1rpx solid #e7e7e7;
border-bottom-right-radius: 15rpx;
}
小结
本次分享一个小程序的模态框封装,具体可以参考vant组件库,封装过程有问题没有解决:蒙版无法遮挡tabbar的问题,这也是历史遗留问题了,我的方案是直接把tabbar隐藏掉,如果有更好的解决方案欢迎小伙伴提出。
Tip:本文写得不是特别详细,适合有小程序基础的小伙伴食用,有问题可在评论区提出哈~~~~
END