小程序的设计没法用第三方框架包,而他自己也没有好用的模态框,只有几个基本弹出框,无法满足业务需求,所以决定自己封装一个模态框组件。
此组件设计了从上下左右四个方向弹出,目前只是测试版本:
传统的模态框就是有个div然后用平滑过渡动画使它弹出。
首先需要考虑动画的选择,由于小程序中js无法控制dom,也就无法控制css,所以用@frame的方式做动画不可取,因为无法给css中传值;
然后考虑到小程序自带的用js控制动画,结果里面全是坑,非常不好用,谁用是知道。
结果只能是用css中自带动画一条路了。
利用transiton和transform:translate解决平滑过渡问题
然后就是高度和模态框的位置可以通过参数控制了
新建出modal组件(新建component)
我尝试先粘代码再解释
modal.wxml:
因为小程序中想用js控制css只有在wxml中添加行内样式接收js参数一种方法,所以我把可变样式都用{{}}方式接收。
showModalStatus控制模态框是否显示,点击x号或者遮罩层模态框消失
这个x号按钮我用了fontawesome字体,由于组件中不能引用外部css,所以需要在引用modal的页面加上字体css,这个字体转css有些麻烦,可以直接用字母x代替他。
组件中一般都需要有slot,用于页面引用时添加自定义标签用的,我这里加了一个slot用于modal名字,一个slot用于modal内容,
多个slot用name区分
modal.xwss:
/*遮罩层*/
.mask{
position: fixed;
width:100%;height:100%;
background:rgba(0,0,0,0.5);
top:0;left:0;
z-index: 10;transition: all 300ms ease-out;
}
/*弹出模态框*/
.mymodal{
width:100%;
position: fixed;z-index: 20;
background:white;height:460px;
border-radius: 10rpx;transition: all 300ms ease-out;
}
.mymodal .mymodal-title{
font-size:30rpx;height:50px;line-height:50px;
border-bottom:1px solid #ddd;
color:#666;padding:0 20px;
display: flex;justify-content:space-between;
align-items: center
}
.mymodal .mymodal-content{
padding:15px;height:320px;overflow: scroll;
}
css就是简单的样式,注意给modal和mask加个transition就行了,动画效果都是动态改变modal的top,left等值,有transition就会有平滑过渡效果
modal.js:
Component({
/**
* 组件的属性列表(共有数据)
*/
properties: {
//modal出现动画类型
fadeStyle: {
type: String,
value: '',
observer(newVal, oldVal, changedPath) {
// 属性被改变时执行的函数(可选),通常 newVal 就是新设置的数据, oldVal 是旧数
if (newVal == "slideUp") {//从下向上滑出
this.setData({
bottom: '-' + this.properties.height,
})
} else if (newVal == "slideDown") {//从上向下滑出
this.setData({
top: '-' + this.properties.height,
})
} else if (newVal == "slideRight") {//从左向右滑出
this.setData({
left: '-' + this.properties.width
})
} else if (newVal == "slideLeft") {//从右向左滑出
this.setData({
right: '-' + this.properties.width
})
}
}
},
width: {
type: String,
value: '100%',
},
height: {
type: String,
value: '',
},
top: {
type: String,
value: ''
},
bottom: {
type: String,
value: ''
},
left: {
type: String,
value: ''
},
right: {
type: String,
value: ''
},
opacity: {
type: String,
value: '0'
},
},
/**
* 组件的初始数据(私有数据)
*/
data: {
//控制模态框打开关闭参数
showModalStatus: false
},
options: {
addGlobalClass: true, //使其可以使用全局样式
multipleSlots: true //使其可以使用多个slot,用name区分
},
/**
* 组件的方法列表
*/
methods: {
//打开模态框
showModal: function(event) {
this.setData({
showModalStatus: true
})
//需要等模态框出现再执行动画,否则无动画效果
setTimeout(function() {
if (this.properties.fadeStyle == "slideUp") {
this.setData({
bottom: 0,
opacity: 1
})
} else if (this.properties.fadeStyle == "slideDown") {
this.setData({
top: 0,
opacity: 1
})
} else if (this.properties.fadeStyle == "slideRight") {
this.setData({
left: 0,
opacity: 1
})
} else if (this.properties.fadeStyle == "slideLeft") {
this.setData({
right: 0,
opacity: 1
})
}
}.bind(this), 100)
},
//关闭模态框
closeModal: function() {
//判断动画样式
if (this.properties.fadeStyle == "slideUp") {
this.setData({
bottom: '-' + this.properties.height,
opacity: 0
})
} else if (this.properties.fadeStyle == "slideDown") {
this.setData({
top: '-' + this.properties.height,
opacity: 0
})
} else if (this.properties.fadeStyle == "slideRight") {
this.setData({
left: '-' + this.properties.width,
opacity: 0
})
} else if (this.properties.fadeStyle == "slideLeft") {
this.setData({
right: '-' + this.properties.width,
opacity: 0
})
}
//等关闭动画完毕后再移除模态框和遮罩
setTimeout(function() {
this.setData({
showModalStatus: false
})
}.bind(this), 400)
}
}
})
组件component中有properties用于存放共有信息和data用于存放私有信息。由于模态框大小和位置采用可控制设计,所以在properties中设置模态框位置参数用于接收引用页面传来的参数。
fadeStyle为动画样式,通过observer监听fadeStyle的变化,判断不同的动画类型而采取不同的方式策略。
我这样设计width和height可以传px也可以传百分数。
然后执行弹出和关闭时都控制一下动画就行了。
值得一提的是当showModalStatus为true时,理论上模态框出现然后执行动画,但貌似modal的出现需要点时间,最好定时100ms后再执行动画,否则会出现动画不稳定
modal.json
{
"component": true,
"usingComponents": {}
}
作为一个组件,需要在json中写上component:true才行
test.json
{
"usingComponents": {
"my-modal": "/assets/components/modal/modal"
}
}
由于json文件比较重要,我放在前面
在需要引用组件的页面的json中,需要写上usingComponents,my-modal为自己起得名字,你起啥名字引用的时候就用啥名字,后面写上组件的路径即可
test.wxml:
这是个自定义模态框
my-modal就是json中自己起得名字
注意写上id,js中调用组件方法需要用到这个id寻找组件
然后就是我们自定义的参数,fadeStyle对应modal.js 中properties中的fadeStyle,要注意在这里设置的参数properties中都是可以接收到的,并且会触发oberver监听。width,height,top等都可以设置
这是个自定义模态框
这是个自定义模态框
这是个自定义模态框
test.js
Page({
data: {
},
onLoad: function (options) {
this.modal = this.selectComponent("#modal");//通过给组件所起的id调用组件
},
showModal:function(){
this.modal.showModal() //调用组件中打开模态框方法
}
})
onload是用前面设置的id把组件调出来加到this中,注意只能是id
然后点击按钮时调用组件打开模态框方法即可
这只是个demo,实战中将自己的内容放到slot中,例如:
这是个自定义模态框
套餐名称
资费,分钟,流量
人气
{{data.PACKAGE_NAME}}
{{data.FEE}},{{data.DURATION}},{{data.FLOW}}
{{data.POPU_VALUE}}
犹豫刚学小程序,好多地方都考虑不周到,这里只是总结一下自己的思路,起码自己目前可以使用
提供个下载吧,不想看废话的可以直接下载看看效果
下载地址:https://download.csdn.net/download/lianzhang861/10980422