本文转自
作者:smallzip
链接:https://www.jianshu.com/p/bd9a4f4b8e6a
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
效果
小程序自定义底部弹出modal框组件,仿照小程序sheet-action的效果,封装成组件直接在其他业务页面公用。
- 底部弹出动画使用的是小程序的animation,弹出动画可以根据自行需求去替换。
- modal顶部有一条短的横线,向下滑动可以触发隐藏modal
- 点击阴影部分可以触发隐藏modal
使用方法
- 在业务页面引入组件
// pages/index/index.json
{"usingComponents": {"product-cart": "../../components/product-cart/index"}
}
// pages/index/index.js
Page({data: {show: false // true:显示 false:隐藏},
showModal(){this.setData({show:true})},
)}
- show参数是boolean值
// pages/index/wswl
<view><button bindtap="showModal">点击</button><product-cart show="{{show}}"></product-cart>
</view>
组件源码
// pages/index/components/buy/index.js
let pageY = 0;
Component({options: {styleIsolation: 'isolated'},/*** 组件的属性列表*/properties: {show: {type: Boolean,value: false}},/*** 组件的初始数据*/data: {list: [{name: '快递',selected: 1,},{name: '自提',selected: 0}],animate: {},hideModal: false, //模态框的状态 false-隐藏 true-显示},/*** 数据监听*/observers: {'show': function(val) {if (val) {this.showModal()} else {this.hideModal()}}},/*** 组件的方法列表*/methods: {// 显示遮罩层showModal() {this.setData({hideModal: true})const animation = wx.createAnimation({duration: 500,timingFunction: 'ease',})// 先显示背景再执行动画,translateY(0)偏移量为0代表显示默认高度setTimeout(() => {animation.translateY(0).step()this.setData({animate: animation.export()})}, 50)},// 隐藏遮罩层hideModal() {const animation = wx.createAnimation({duration: 500,timingFunction: 'ease',})// 设置为100vh可以确保滚动到底部,可以按照自己的内容高度设置,能够滑到底部即可animation.translateY('100vh').step()this.setData({animate: animation.export(),})// 先执行动画,再隐藏组件setTimeout(() => {this.setData({hideModal: false})}, 300)},// 移动touchMove(e) {const clientY = e.changedTouches[0].clientYif (clientY - pageY > 0 && clientY - pageY > 50) {this.hideModal()}},// 触摸开始touchStart(e) {pageY = e.changedTouches[0].clientY;},// 选择类型changeItem(e) {const {index} = e.currentTarget.datasetthis.data.list.forEach((e, i) => {if (i == index) {e.selected = 1} else {e.selected = 0}})this.setData({list: this.data.list})},// 确认confirm() {this.hideModal()},}
})
<!--pages/index/components/buy/index.wxml-->
<view class="box" hidden="{{!hideModal}}"><view class="empty-box" bindtap="hideModal" id="empty-box"></view><scroll-view scroll-y style="max-height:80vh;"><view class="content" style="transform:translateY({{translateY}}px);" animation="{{animate}}"><!-- boll --><view class="header" bindtouchstart="touchStart" bindtouchmove="touchMove"><view></view></view><!-- 快递类型 --><view><view class="item" wx:for="{{list}}" wx:key="index" bindtap="changeItem" data-index="{{index}}"><view class="item-name">{{item.name}}</view><view><view class="item-no-selected" wx:if="{{item.selected==0}}"></view><image class="item-selected" wx:if="{{item.selected==1}}" src="/assets/images/choose.png"></image></view></view></view><!-- 按钮 --><view class="button" bindtap="confirm"><view>确认</view></view></view></scroll-view>
</view>
/* pages/index/components/buy/index.wxss */.flex {display: flex;align-items: center;
}.box {position: fixed;top: 0;left: 0;right: 0;bottom: 0;z-index: 1000;width: 100vw;height: 100vh;background: rgba(0, 0, 0, 0.5);display: flex;flex-direction: column;
}.empty-box {flex: 1;background-color: transparent;
}/* 内容视图 */.content {width: 100vw;background: rgba(255, 255, 255, 1);opacity: 1;border-radius: 20px 20px 0px 0px;z-index: 1001;
}/* 头部 */.header {position: relative;height: 80rpx;width: 100vw;
}.header > view {position: absolute;top: 26rpx;left: calc(50vw - 30rpx);width: 60rpx;height: 10rpx;background: rgba(161, 166, 175, 1);opacity: 0.6;border-radius: 6rpx;
}/* 快递 */.item {display: flex;align-items: center;justify-content: space-between;width: calc(100vw - 80rpx);padding: 0 40rpx;height: 100rpx;background: rgba(255, 255, 255, 1);opacity: 1;
}.item-no-selected {width: 36rpx;height: 36rpx;background: rgba(255, 255, 255, 1);border: 2rpx solid rgba(112, 112, 112, 1);border-radius: 50%;opacity: 0.5;
}.item-selected {width: 40rpx;height: 40rpx;
}/* 按钮 */.button {width: 100vw;padding: 80rpx 40rpx 20rpx 40rpx;
}.button >view {width: calc(100% - 80rpx);height: 98rpx;border-radius: 50rpx;line-height: 98rpx;text-align: center;font-size: 32rpx;font-family: PingFang SC;font-weight: bold;color: rgba(255, 255, 255, 1);background: rgba(237, 58, 74, 1);opacity: 1;
}
作者:smallzip
链接:https://www.jianshu.com/p/bd9a4f4b8e6a
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。