缘起
微信小程序官方提供的picker样式不好控制,跟其他样式不统一,也没法进行其他操作,不如自定义一个,使用:picker-view封装为一个组件。 代码现成,直接复制过去用吧。
效果
组件代码
haiweidate.wxml
<view class="container">
<view class="page-body">
<view wx:if="{{showTitle === 'true'}}" class="selected-date">{{year}}年{{month}}月{{day}}日</view>
<picker-view indicator-class="indicator" value="{{value}}" bindchange="bindChange">
<picker-view-column>
<view wx:for="{{years}}" wx:key="{{years}}" >{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{months}}" wx:key="{{months}}" >{{item}}月</view>
</picker-view-column>
<!-- 28天的 -->
<picker-view-column hidden="{{mouthContainDayCount !== 28}}">
<view wx:for="{{days28}}" wx:key="*this" >{{item}}日</view>
</picker-view-column>
<!-- 29天的 -->
<picker-view-column hidden="{{mouthContainDayCount !== 29}}">
<view wx:for="{{days29}}" wx:key="*this" >{{item}}日</view>
</picker-view-column>
<!-- 30天的 -->
<picker-view-column hidden="{{mouthContainDayCount !== 30}}">
<view wx:for="{{days30}}" wx:key="*this" >{{item}}日</view>
</picker-view-column>
<!-- 31天的 -->
<picker-view-column hidden="{{mouthContainDayCount !== 31}}">
<view wx:for="{{days31}}" wx:key='*this' >{{item}}日</view>
</picker-view-column>
</picker-view>
</view>
</view>
haiweidate.less
.container{
padding: 50rpx;
.page-body{
.selected-date{
width: 100%;
text-align: center;
font-size: 36rpx;
font-weight: 600;
padding: 30rpx;
}
.indicator{
height: 100rpx;
border-bottom: 1rpx solid #767676;
}
picker-view{
width: 100%;
height: 300rpx;
picker-view-column{
view{
line-height: 100rpx;
text-align: center;
}
}
}
}
}
haiweidate.js
Component({
properties: {
today:{
type:String,
value:''
},
showTitle:{
type:String,
value:"true"
}
},
data: {
years:[],
year: '',
months:[],
month: '',
days31:[],
days30:[],
days29:[],
days28:[],
day: '',
// 年 月 28 29 30 31 这个顺序对应picker-view-column的前后位置
value: [],
mouthContainDayCount:31,
},
methods: {
// 初始化数据
initData(){
const date = new Date()
const years = []
const months = []
const days31 = []
const days30 = []
const days29 = []
const days28 = []
for (let i = 1980; i <= date.getFullYear(); i++) {
years.push(i)
}
for (let i = 1; i <= 12; i++) {
months.push(i)
}
for (let i = 1; i <= 28; i++) {
days31.push(i);
days30.push(i);
days29.push(i);
days28.push(i);
}
days31.push(29);
days30.push(29);
days29.push(29);
days31.push(30);
days30.push(30);
days31.push(31);
this.setData({
years,
months,
days31,
days30,
days29,
days28
});
this.setData({
value:[0, 0, 31,31,31,31]
});
},
// 解析当前时间
parseToday(){
const {today} = this.properties;
const {years} = this.data;
let date = null;
if(today === '' || today === undefined){
date = new Date();
}else{
date = this._stringToDate(today);
}
let year = date.getFullYear();
let month = date.getMonth()+1;
let day = date.getDate();
let value = [year - years[0] ,
month-1,
day-1,
day-1,
day-1,
day-1];
this.setData({
value,
year,
month,
day
});
},
/* 获取每月天数 */
_getMonthDay(year, month){
let count = 31;
switch (month) {
case 4:
case 6:
case 9:
case 11:
count = 30
break;
case 2:
count = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)
? 29: 28
break;
}
return count;
},
// 获取下标
getDayIndex(){
/**
* value 数组对应的列
* 年 月 28 29 30 31
* 0 1 2 3 4 5
* 公式:index === mouthContainDayCount - 26
* */
return this.data.mouthContainDayCount - 26;
},
// change事件
bindChange(e){
const {value} = e.detail;
const [y,m] = value;
// 获取原始天数下标
let index = this.getDayIndex();
let d = e.detail.value[index];
const { years,months} = this.data;
const newMonthDaysCount = this._getMonthDay(years[y],months[m]);
if(this.data.mouthContainDayCount !== newMonthDaysCount ){
this.setData({
mouthContainDayCount:newMonthDaysCount ,
value: [y,m,15,15,15,15,15]
});
// 改变上面展示的数据
d = 15;
};
this.setData({
year:years[y],
month:months[m],
day:d+1,
});
const { year, month, day} = this.data;
this.triggerEvent('callback',{
year,
month,
day,
value:year+'-'+month+'-'+day
});
},
// 转换格式 2022-2-23 转换为 2202/2/23 然后Date封装
_stringToDate(str) {
if(str === undefined || str === null || str.length ===0){
return new Date();
}
str = str.replace(/-/g, "/");
return new Date(str);
}
},
// 这个阶段properties还没有值
created: function(){
},
attached: function(){
},
ready: function(){
this.initData();
this.parseToday();
},
moved: function(){
},
detached: function(){
},
});
父组件调用
json
{
"usingComponents": {
"wktdate":"/components/haiweidate/haiweidate"
}
}
xml
today="2202-5-26" 刚进去的时候展示的时间
showTitle="false" 是否展示表头,可以视为为“true”看看效果
bindcallback="handleCallback" 回调函数
<haiweidate class="date_warp" today="2202-5-26" showTitle="false"
bindcallback="handleCallback"
></haiweidate>
JS
value 的格式就是YYYY-MM-DD格式
handleCallback({year,month,day,value}){
// value== '2022-2-34'
},
都看这了,应该对你有帮助,来个赞不过分吧。如果有问题,请留言
END