组件化开发是一种将大型软件系统分解为更小、更易于管理和复用的独立模块或组件的方法。这种方法在现代软件开发中越来越受到重视,尤其是在前端开发领域。微信小程序的日期区间选择组件的使用
wxml 代码
html
<view>
<view bind:tap="chooseData">{{ rendunTime || '请选择开始时间和结束时间'}}</view>
<sx-data-picker show="{{isShowData}}" bind:confirm="getDataSlot"></sx-data-picker>
</view>
js 代码
js
Page({
data: {
isShowData:false,
rendunTime:""
},
chooseData(){
this.setData({
isShowData:!this.isShowData
})
},
getDataSlot(e){
let time = `${e.detail.start} 至 ${e.detail.end}`
this.setData({
rendunTime:time
})
}
})
微信小程序的日期区间选择组件的封装
wxml布局代码
html
<!-- 遮罩层的样式 -->
<view class="page" bindtouchmove="touchMove" hidden="{{!hideModal}}" wx:if="{{show}}">
<!-- 内容视图样式 -->
<view class="content" style="transform:translateY({{translateY}}px);" animation="{{animate}}">
<view class="header" bindtouchstart="touchStart">
<image class="headerFork" bindtap="hideModal" src="/static/images/close.png"></image>
<view class="time" >
<view class="time_text">
<view>开始时间:{{startyear}}年{{startmonth}}月{{startday}}日</view>
</view>
<view class="item_time">
<picker-view indicator-class="picker_active" mask-class="mask" value="{{startvalue}}" data-type="start" style="width: 100%; height: 200rpx;" bindchange="bindChange">
<picker-view-column>
<view class="timeText" wx:for="{{years}}" wx:key="index">{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view class="timeText" wx:for="{{months}}" wx:key="index" bindchange="monthChange">{{item}}月</view>
</picker-view-column>
<picker-view-column>
<view class="timeText" wx:for="{{days}}" wx:key="index">{{item}}日</view>
</picker-view-column>
</picker-view>
</view>
<view class="time_text">
<view>结束时间:{{endyear}}年{{endmonth}}月{{endday}}日</view>
</view>
<view class="item_time">
<picker-view indicator-class="picker_active" mask-class="mask" style="width: 100%; height: 200rpx;" value="{{endvalue}}" data-type="end" bindchange="bindChange">
<picker-view-column>
<view class="timeText" wx:for="{{years}}" wx:key="index">{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view class="timeText" wx:for="{{months}}" wx:key="index">{{item}}月</view>
</picker-view-column>
<picker-view-column>
<view class="timeText" wx:for="{{days}}" wx:key="index">{{item}}日</view>
</picker-view-column>
</picker-view>
</view>
</view>
</view>
<!-- 按钮 -->
<view class="button" bindtap="confirm">
<view class="view">确认</view>
</view>
</view>
</view>
wxss样式代码
css
.page {
position: fixed;
top: 0;
left: 0;
z-index: 1000;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.content {
width: 100vw;
background: rgba(255, 255, 255, 1);
border-radius: 16rpx 16rpx 0rpx 0rpx;
}
.header {
width: 100vw;
padding: 24rpx 50rpx;
box-sizing: border-box;
}
.header .headerFork {
position: absolute;
top: 26rpx;
left: calc(100% - 60rpx);
width: 36rpx;
height: 36rpx;
opacity: 0.3;
border-radius: 50%;
}
.headerContent {
width: 198rpx;
height: 198rpx;
border-radius: 8rpx;
}
.headerContent .headerContentImage {
width: 100%;
height: 100%;
border-radius: 8rpx;
}
.header .money {
font-size: 48rpx;
font-family: Medium;
font-weight: 500;
color: #FA5151;
margin-left: 24rpx;
}
.smallMoney {
font-size: 30rpx;
}
.header>.headerNumber>.name {
height: 30rpx;
font-size: 30rpx;
font-family: Medium;
font-weight: 500;
color: #181818;
line-height: 30rpx;
}
.button {
width: 100vw;
padding: 32rpx 24rpx;
border-top: 2rpx solid #f5f5f5;
position: relative;
z-index: 100;
}
.button .view {
width: calc(100% - 48rpx);
height: 80rpx;
border-radius: 50rpx;
line-height: 80rpx;
text-align: center;
font-size: 30rpx;
font-family: Regular;
font-weight: 400;
color: #fff;
background: #409eff;
opacity: 1;
}
.timeText{
font-size: 28rpx;
line-height: 68rpx;
font-family: Medium;
font-weight: 500;
color: #181818;
text-align: center;
}
.time_text {
text-align: center;
margin-top: 32rpx;
margin-bottom: 14rpx;
font-size: 30rpx;
font-family: Medium;
font-weight: 500;
color: #181818;
}
js 逻辑代码
js
let pageY = 0
const date = new Date()
const years = []
const months = []
const days = []
// 获取当前日期的年月日
var currentYear = new Date().getFullYear();
var currentMonth = new Date().getMonth() + 1;
var currentDate = new Date().getDate();
// 当前月份包含的天数
var maxDate = new Date(currentYear, currentMonth, 0).getDate();
// 所有的年份
for (let i = 1990; i <= date.getFullYear(); i++) {
years.push(i)
}
// 所有的月份
for (let i = 1; i <= 12; i++) {
months.push((i + "").padStart(2, '0'))
}
// 当前月份包含的所有天数
for (let i = 1; i <= maxDate; i++) {
days.push((i + "").padStart(2, '0'))
}
Component({
options: {
styleIsolation: 'isolated', //样式隔离
},
/**
* 组件的属性列表
*/
properties: {
show: {
type: Boolean,
value: false
},
},
/**
* 数据监听
*/
observers: {
'show': function (value) {
if (value) {
this.showModal()
} else {
this.hideModal()
}
}
},
/**
* 组件的初始数据
*/
data: {
// 时间控件
years: years,
months: months,
days: days,
// 开始日期文字
startyear: '',
startmonth: '',
startday: '',
// 时间控件开始时间
startvalue: [],
// 结束日期文字
endyear: '',
endmonth: '',
endday: '',
// 时间控件结束时间
endvalue: [],
animate: '',
hideModal: false, //模态框的状态 false-隐藏 true-显示
},
/**
* 组件的方法列表
*/
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()
})
this.timeShow()
}, 0)
},
// 隐藏遮罩层
hideModal() {
const animation = wx.createAnimation({
duration: 500,
timingFunction: 'ease',
})
// 设置为100vh可以确保滚动到底部,可以按照自己的内容高度设置,能够滑到底部即可
animation.translateY('100vh').step()
this.setData({
animate: animation.export(),
})
// 先执行动画,再隐藏组件
setTimeout(() => {
this.setData({
hideModal: false
})
this.triggerEvent('hideModal', true)
}, 300)
},
// 移动
touchMove(e) {
const clientY = e.changedTouches[0].clientY
if (clientY - pageY > 0 && clientY - pageY > 50) {
this.hideModal()
}
},
// 触摸开始
touchStart(e) {
pageY = e.changedTouches[0].clientY
},
// 时间更改
bindChange(e) {
const val = e.detail.value;
var newDays = [];
var maxDate = new Date(this.data.years[val[0]], this.data.months[val[1]], 0).getDate();
// 选择月份包含的所有天数
for (let i = 1; i <= maxDate; i++) {
newDays.push((i + "").padStart(2, '0'))
}
// 时间文字内容更改
if (e.target.dataset.type == 'start') { //开始时间
//判断月份是否发生改变---月份改变 对应的当月包含天数改变并且定位到1号
if (this.data.startmonth != this.data.months[val[1]]) {
this.setData({
days: newDays,
startvalue: [val[0], val[1], 0],
startyear: this.data.years[val[0]],
startmonth: this.data.months[val[1]],
startday: days[0]
})
} else {
this.setData({
startyear: this.data.years[val[0]],
startmonth: this.data.months[val[1]],
startday: this.data.days[val[2]]
})
}
} else { //结束时间
//判断月份是否发生改变---月份改变 对应的当月包含天数改变并且定位到1号
console.log(days[0])
if (this.data.endmonth != this.data.months[val[1]]) {
this.setData({
days: newDays,
endvalue: [val[0], val[1], 0],
endyear: this.data.years[val[0]],
endmonth: this.data.months[val[1]],
endday: days[0]
})
} else {
this.setData({
days: newDays,
endyear: this.data.years[val[0]],
endmonth: this.data.months[val[1]],
endday: this.data.days[val[2]]
})
}
}
},
timeShow() {
// 获取时间控件---默认的开始时间和结束时间
var defaultYear = years.length - 1;
var defaultMonth = currentMonth;
var defaultDate = currentDate - 1;
this.setData({
// 开始日期文字
startyear: currentYear,
startmonth: currentMonth,
startday: currentDate,
// 时间控件开始时间
startvalue: [defaultYear, defaultMonth, defaultDate],
// 结束日期文字
endyear: currentYear,
endmonth: currentMonth,
endday: currentDate,
// 时间控件结束时间
endvalue: [defaultYear, defaultMonth, defaultDate],
})
},
// 确认按钮事件
confirm() {
let {
startyear,
startmonth,
startday,
endyear,
endmonth,
endday
} = this.data
let obj = {
start: startyear + '-' + startmonth + '-' + startday, //开始时间
end: endyear + '-' + endmonth + '-' + endday //结束时间
}
this.hideModal()
this.triggerEvent('confirm', obj)
},
},
})
如果这篇文章对你有所帮助,欢迎点赞、分享和留言,让更多的人受益。感谢你的细心阅读,如果你发现了任何错误或需要补充的地方,请随时告诉我,我会尽快处理。