<template> <view> <view @tap.stop="open"><slot></slot></view> <view class="graceDateTime" v-if="show" @touchmove.stop="" @tap.self="close" :style="{backgroundColor:background}"></view> <view class="graceDateTime-body" :class="[show?'gdIn':'gdOut']" @touchmove.stop="" :style="{paddingBottom:paddingBottom}"> <view class="graceDateTime-header grace-space-between" v-if="isHeaderBar"> <text class="graceDateTime-header-btn" :style="{color:cancelTColor}" @tap="close">{{cancelText}}</text> <text class="graceDateTime-header-btn" :style="{textAlign:'right', color:confirmColor}" @tap="confirm">{{confirmText}}</text> </view> <picker-view :indicator-style="indicatorStyle" class="graceDateTime-main" :value="defaultVal" @change="change" :style="{height:height}"> <picker-view-column> <text class="graceDateTime-item" v-for="(item, index) in sDate[0]" :key="index">{{item}}{{units[0]}}</text> </picker-view-column> <picker-view-column> <text class="graceDateTime-item" v-for="(item, index) in sDate[1]" :key="index">{{item}}{{units[1]}}</text> </picker-view-column> <picker-view-column> <text class="graceDateTime-item" v-for="(item, index) in sDate[2]" :key="index">{{item}}{{units[2]}}</text> </picker-view-column> <picker-view-column v-if="isTime"> <text class="graceDateTime-item" v-for="(item, index) in sDate[3]" :key="index">{{item}}{{units[3]}}</text> </picker-view-column> <picker-view-column v-if="isTime"> <text class="graceDateTime-item" v-for="(item, index) in sDate[4]" :key="index">{{item}}{{units[4]}}</text> </picker-view-column> <picker-view-column v-if="isTime && isSecond"> <text class="graceDateTime-item" v-for="(item, index) in sDate[5]" :key="index">{{item}}{{units[5]}}</text> </picker-view-column> </picker-view> </view> </view> </template> <script> export default { props: { background:{ type : String, default : 'rgba(0, 0, 0, 0.5)' }, cancelText : { type : String, default : '取消' }, cancelTColor : { type : String, default : '#888888' }, confirmText : { type : String, default : '确定' }, confirmColor : { type : String, default : '#3688FF' }, value : { type : String , default:''}, isTime : {type : Boolean, default : true}, isSecond : {type : Boolean, default : true}, startYear : {type : Number, default : 1980}, endYear : {type : Number, default : 2050}, units : {type : Array , default:function(){return new Array('年','月','日','时','分','秒')}}, height:{ type : String, default : '300rpx' }, isHeaderBar : {type : Boolean, default : true}, paddingBottom:{type : String , default:'0rpx'} }, data() { return { show:false, indicatorStyle : 'height:35px', defaultVal : [0,0,0,0,0,0], sDate:[[],[],[],[],[],[]] } }, created() { this.init(); }, methods: { now : function () { var date = new Date(); var y = date.getFullYear(); var m = date.getMonth() + 1; m = m < 10 ? ('0' + m) : m; var d = date.getDate(); d = d < 10 ? ('0' + d) : d; var h = date.getHours(); h = h < 10 ? ('0' + h) : h; var minute = date.getMinutes(); var second = date.getSeconds(); minute = minute < 10 ? ('0' + minute) : minute; second = second < 10 ? ('0' + second) : second; return y + '-' + m + '-' + d + ' '+ h +':' + minute + ':' + second; }, arrayIndexOf : function(arr, needFind){ var index = -1; for(let i = 0; i < arr.length; i++){if(arr[i] == needFind){index = i; return i;}} return index; }, setValue : function (val) { console.log(val); if(val == ''){val = this.now();} var reg = /^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/; var res = val.match(reg); if(res == null){ reg = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/; res = val.match(reg); if(res == null){ this.setValue(this.now()); return ; } res[4] = '00'; res[5] = '00'; res[6] = '00'; } this.setDefaults([res[1],res[2],res[3],res[4],res[5],res[6]]); }, setDefaults : function (res) { for(let i = 0; i < res.length; i++){ var index = this.arrayIndexOf(this.sDate[i], res[i]); if(index == -1){index = 0;} this.defaultVal.splice(i, 1, index); } this.changeBase(this.defaultVal); }, // 初始化组件 init:function(){ if(this.startYear < 1970){this.startYear = 1970;} if(this.endYear < this.startYear){this.endYear = this.startYear + 10;} var years = new Array(); for(let i = this.startYear; i <= this.endYear; i++){years.push(i);} var months = new Array(); for(let i = 1; i <= 12; i++){if(i < 10){months.push('0'+i);}else{months.push(i);}} var days = new Array(); for(let i = 1; i <= 31; i++){if(i < 10){days.push('0'+i);}else{days.push(i);}} var hours = new Array(); for(let i = 0; i < 24; i++){if(i < 10){hours.push('0'+i);}else{hours.push(i);}} var minutes = new Array(); var seconds = new Array(); for(let i = 0; i < 60; i++){ if(i < 10){minutes.push('0'+i); seconds.push('0'+i);}else{minutes.push(i); seconds.push(i);} } this.sDate = [years, months, days, hours, minutes, seconds]; this.$nextTick(()=>{setTimeout(()=>{ this.setValue(this.value);},800);}); }, change : function (res) { this.changeBase(res.detail.value); }, changeBase:function(res){ var date = new Date(this.sDate[0][res[0]], this.sDate[1][res[1]], 0); var days = date.getDate(); var daysOut = new Array(); for(let i = 1; i <= days; i++){if(i < 10){daysOut.push('0'+i);}else{daysOut.push(i);}} this.sDate.splice(2, 1, daysOut); this.defaultVal = res; if(this.isTime){ var resdata = new Array(this.sDate[0][this.defaultVal[0]], this.sDate[1][this.defaultVal[1]], this.sDate[2][this.defaultVal[2]], this.sDate[3][this.defaultVal[3]], this.sDate[4][this.defaultVal[4]], this.sDate[5][this.defaultVal[5]]); }else{ var resdata = new Array(this.sDate[0][this.defaultVal[0]], this.sDate[1][this.defaultVal[1]], this.sDate[2][this.defaultVal[2]]) } this.$emit('change', resdata); }, confirm:function () { if(this.isTime){ var res = new Array(this.sDate[0][this.defaultVal[0]], this.sDate[1][this.defaultVal[1]], this.sDate[2][this.defaultVal[2]], this.sDate[3][this.defaultVal[3]], this.sDate[4][this.defaultVal[4]], this.sDate[5][this.defaultVal[5]]); }else{ var res = new Array(this.sDate[0][this.defaultVal[0]], this.sDate[1][this.defaultVal[1]], this.sDate[2][this.defaultVal[2]]) } this.$emit('confirm', res); this.show = false; }, open : function () { this.show = true; }, close : function () { this.show = false; } } } </script> <style scoped> .graceDateTime{position:fixed; width:100%; height:100%; top:0; left:0; bottom:0; z-index:998;} .graceDateTime-body{background-color:#FFFFFF; position:fixed; z-index:999; bottom:-1000px; left:0; width:100%;} .graceDateTime-header{padding:25rpx;} .graceDateTime-header-btn{width:200rpx; line-height:38rpx; height:38rpx; display:block; font-size:28rpx;} .graceDateTime-main{width:100%;} .graceDateTime-item{display:block; width:100%; height:35px; font-size:28rpx; line-height:35px; overflow:hidden; text-align:center;} @keyframes gdIn{ from {bottom:-1000px; } 100% { bottom: 0px; }} .gdIn {animation:gdIn 200ms ease-in forwards;} @keyframes gdOut{ from {bottom:0px;} 100% { bottom:-1000px; }} .gdOut {animation:gdOut 200ms ease-out forwards;} </style>