graceDateTime.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <template>
  2. <view>
  3. <view @tap.stop="open"><slot></slot></view>
  4. <view class="graceDateTime" v-if="show" @touchmove.stop.prevent="" @tap.self="close" :style="{backgroundColor:background}"></view>
  5. <view class="graceDateTime-body" :class="[show?'gdIn':'gdOut']" @touchmove.stop.prevent="" :style="{paddingBottom:paddingBottom}">
  6. <view class="graceDateTime-header grace-space-between" v-if="isHeaderBar">
  7. <text class="graceDateTime-header-btn" :style="{color:cancelTColor}" @tap="close">{{cancelText}}</text>
  8. <text class="graceDateTime-header-btn" :style="{textAlign:'right', color:confirmColor}" @tap="confirm">{{confirmText}}</text>
  9. </view>
  10. <picker-view :indicator-style="indicatorStyle" class="graceDateTime-main" :value="defaultVal"
  11. @change="change" :style="{height:height}">
  12. <picker-view-column>
  13. <text class="graceDateTime-item" v-for="(item, index) in sDate[0]" :key="index">{{item}}{{units[0]}}</text>
  14. </picker-view-column>
  15. <picker-view-column>
  16. <text class="graceDateTime-item" v-for="(item, index) in sDate[1]" :key="index">{{item}}{{units[1]}}</text>
  17. </picker-view-column>
  18. <picker-view-column>
  19. <text class="graceDateTime-item" v-for="(item, index) in sDate[2]" :key="index">{{item}}{{units[2]}}</text>
  20. </picker-view-column>
  21. <picker-view-column v-if="isTime">
  22. <text class="graceDateTime-item" v-for="(item, index) in sDate[3]" :key="index">{{item}}{{units[3]}}</text>
  23. </picker-view-column>
  24. <picker-view-column v-if="isTime">
  25. <text class="graceDateTime-item" v-for="(item, index) in sDate[4]" :key="index">{{item}}{{units[4]}}</text>
  26. </picker-view-column>
  27. <picker-view-column v-if="isTime && isSecond">
  28. <text class="graceDateTime-item" v-for="(item, index) in sDate[5]" :key="index">{{item}}{{units[5]}}</text>
  29. </picker-view-column>
  30. </picker-view>
  31. </view>
  32. </view>
  33. </template>
  34. <script>
  35. export default {
  36. props: {
  37. background:{ type : String, default : 'rgba(0, 0, 0, 0.5)' },
  38. cancelText : { type : String, default : '取消' },
  39. cancelTColor : { type : String, default : '#888888' },
  40. confirmText : { type : String, default : '确定' },
  41. confirmColor : { type : String, default : '#3688FF' },
  42. value : { type : String , default:''},
  43. isTime : {type : Boolean, default : true},
  44. isSecond : {type : Boolean, default : true},
  45. startYear : {type : Number, default : 1980},
  46. endYear : {type : Number, default : 2050},
  47. units : {type : Array , default:function(){return new Array('年','月','日','时','分','秒')}},
  48. height:{ type : String, default : '300rpx' },
  49. isHeaderBar : {type : Boolean, default : true},
  50. paddingBottom:{type : String , default:'0rpx'}
  51. },
  52. data() {
  53. return {
  54. show:false,
  55. indicatorStyle : 'height:35px',
  56. defaultVal : [0,0,0,0,0,0],
  57. sDate:[[],[],[],[],[],[]]
  58. }
  59. },
  60. created() {
  61. this.init();
  62. },
  63. methods: {
  64. now : function () {
  65. var date = new Date();
  66. var y = date.getFullYear();
  67. var m = date.getMonth() + 1;
  68. m = m < 10 ? ('0' + m) : m;
  69. var d = date.getDate();
  70. d = d < 10 ? ('0' + d) : d;
  71. var h = date.getHours();
  72. h = h < 10 ? ('0' + h) : h;
  73. var minute = date.getMinutes();
  74. var second = date.getSeconds();
  75. minute = minute < 10 ? ('0' + minute) : minute;
  76. second = second < 10 ? ('0' + second) : second;
  77. return y + '-' + m + '-' + d + ' '+ h +':' + minute + ':' + second;
  78. },
  79. arrayIndexOf : function(arr, needFind){
  80. var index = -1;
  81. for(let i = 0; i < arr.length; i++){if(arr[i] == needFind){index = i; return i;}}
  82. return index;
  83. },
  84. setValue : function (val) {
  85. if(val == ''){val = this.now();}
  86. var reg = /^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/;
  87. var res = val.match(reg);
  88. if(res == null){
  89. reg = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/;
  90. res = val.match(reg);
  91. if(res == null){
  92. this.setValue(this.now());
  93. return ;
  94. }
  95. res[4] = '00';
  96. res[5] = '00';
  97. res[6] = '00';
  98. }
  99. this.setDefaults([res[1],res[2],res[3],res[4],res[5],res[6]]);
  100. },
  101. setDefaults : function (res) {
  102. for(let i = 0; i < res.length; i++){
  103. var index = this.arrayIndexOf(this.sDate[i], res[i]);
  104. if(index == -1){index = 0;}
  105. this.defaultVal.splice(i, 1, index);
  106. }
  107. this.changeBase(this.defaultVal);
  108. },
  109. // 初始化组件
  110. init:function(){
  111. if(this.endYear < this.startYear){this.endYear = this.startYear + 10;}
  112. var years = new Array();
  113. for(let i = this.startYear; i <= this.endYear; i++){years.push(i);}
  114. var months = new Array();
  115. for(let i = 1; i <= 12; i++){if(i < 10){months.push('0'+i);}else{months.push(i);}}
  116. var days = new Array();
  117. for(let i = 1; i <= 31; i++){if(i < 10){days.push('0'+i);}else{days.push(i);}}
  118. var hours = new Array();
  119. for(let i = 0; i < 24; i++){if(i < 10){hours.push('0'+i);}else{hours.push(i);}}
  120. var minutes = new Array();
  121. var seconds = new Array();
  122. for(let i = 0; i < 60; i++){
  123. if(i < 10){minutes.push('0'+i); seconds.push('0'+i);}else{minutes.push(i); seconds.push(i);}
  124. }
  125. this.sDate = [years, months, days, hours, minutes, seconds];
  126. this.$nextTick(()=>{setTimeout(()=>{ this.setValue(this.value);},800);});
  127. },
  128. change : function (res) {
  129. this.changeBase(res.detail.value);
  130. },
  131. changeBase:function(res){
  132. var date = new Date(this.sDate[0][res[0]], this.sDate[1][res[1]], 0);
  133. var days = date.getDate();
  134. var daysOut = new Array();
  135. for(let i = 1; i <= days; i++){
  136. if(i < 10){daysOut.push('0'+i);}else{daysOut.push(i);}
  137. }
  138. this.sDate.splice(2, 1, daysOut);
  139. if(res[2] + 1 > days){res[2] = days - 1;}
  140. this.defaultVal = res;
  141. if(this.isTime){
  142. var resdata = new Array(this.sDate[0][this.defaultVal[0]],
  143. this.sDate[1][this.defaultVal[1]],
  144. this.sDate[2][this.defaultVal[2]],
  145. this.sDate[3][this.defaultVal[3]],
  146. this.sDate[4][this.defaultVal[4]],
  147. this.sDate[5][this.defaultVal[5]]);
  148. }else{
  149. var resdata = new Array(this.sDate[0][this.defaultVal[0]],
  150. this.sDate[1][this.defaultVal[1]],
  151. this.sDate[2][this.defaultVal[2]])
  152. }
  153. this.$emit('change', resdata);
  154. },
  155. confirm:function () {
  156. if(this.isTime){
  157. var res = new Array(this.sDate[0][this.defaultVal[0]],
  158. this.sDate[1][this.defaultVal[1]],
  159. this.sDate[2][this.defaultVal[2]],
  160. this.sDate[3][this.defaultVal[3]],
  161. this.sDate[4][this.defaultVal[4]],
  162. this.sDate[5][this.defaultVal[5]]);
  163. }else{
  164. var res = new Array(this.sDate[0][this.defaultVal[0]],
  165. this.sDate[1][this.defaultVal[1]],
  166. this.sDate[2][this.defaultVal[2]])
  167. }
  168. this.$emit('confirm', res);
  169. this.show = false;
  170. },
  171. open : function () {
  172. this.show = true;
  173. },
  174. close : function () {
  175. this.show = false;
  176. }
  177. }
  178. }
  179. </script>
  180. <style scoped>
  181. .graceDateTime{position:fixed; width:100%; height:100%; top:0; left:0; bottom:0; z-index:998;}
  182. .graceDateTime-body{background-color:#FFFFFF; position:fixed; z-index:999; bottom:-1000px; left:0; width:100%;}
  183. .graceDateTime-header{padding:25rpx;}
  184. .graceDateTime-header-btn{width:200rpx; line-height:38rpx; height:38rpx; display:block; font-size:28rpx;}
  185. .graceDateTime-main{width:100%;}
  186. .graceDateTime-item{display:block; width:100%; height:35px; font-size:28rpx; line-height:35px; overflow:hidden; text-align:center;}
  187. @keyframes gdIn{ from {bottom:-1000px; } 100% { bottom: 0px; }}
  188. .gdIn {animation:gdIn 200ms ease-in forwards;}
  189. @keyframes gdOut{ from {bottom:0px;} 100% { bottom:-1000px; }}
  190. .gdOut {animation:gdOut 200ms ease-out forwards;}
  191. </style>