gui-datetime.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <template>
  2. <view>
  3. <view
  4. @tap.stop="open"><slot></slot></view>
  5. <view
  6. class="gui-dateBT-shade gui-flex gui-columns gui-justify-content-end"
  7. v-if="show"
  8. :style="{zIndex:zIndex, width:width}">
  9. <view
  10. class="graceDateTime-header gui-flex gui-rows gui-space-between gui-bg-gray">
  11. <text
  12. class="graceDateTime-header-btn"
  13. :style="{color:cancelTColor}"
  14. @tap="close">{{cancelText}}</text>
  15. <text
  16. class="graceDateTime-header-btn"
  17. :style="{textAlign:'right', color:confirmColor}"
  18. @tap="confirm">{{confirmText}}</text>
  19. </view>
  20. <view
  21. class="gui-bg-white">
  22. <picker-view
  23. :indicator-style="indicatorStyle"
  24. class="graceDateTime-main"
  25. :value="defaultVal"
  26. @change="change"
  27. :style="{height:height, width:width}">
  28. <picker-view-column>
  29. <view
  30. class="graceDateTime-item"
  31. :style="indicatorStyle"
  32. v-for="(item, index) in sDate[0]"
  33. :key="index">
  34. <text
  35. class="graceDateTime-item gui-block-text"
  36. :style="indicatorStyle">{{item}}{{units[0]}}</text>
  37. </view>
  38. </picker-view-column>
  39. <picker-view-column>
  40. <view
  41. class="graceDateTime-item"
  42. :style="indicatorStyle"
  43. v-for="(item, index) in sDate[1]"
  44. :key="index">
  45. <text
  46. class="graceDateTime-item gui-block-text"
  47. :style="indicatorStyle">{{item}}{{units[1]}}</text>
  48. </view>
  49. </picker-view-column>
  50. <picker-view-column>
  51. <view
  52. class="graceDateTime-item"
  53. :style="indicatorStyle"
  54. v-for="(item, index) in sDate[2]"
  55. :key="index">
  56. <text
  57. class="graceDateTime-item gui-block-text"
  58. :style="indicatorStyle">{{item}}{{units[2]}}</text>
  59. </view>
  60. </picker-view-column>
  61. <picker-view-column
  62. v-if="isTime">
  63. <view
  64. class="graceDateTime-item"
  65. :style="indicatorStyle"
  66. v-for="(item, index) in sDate[3]"
  67. :key="index">
  68. <text
  69. class="graceDateTime-item gui-block-text"
  70. :style="indicatorStyle">{{item}}{{units[3]}}</text>
  71. </view>
  72. </picker-view-column>
  73. <picker-view-column
  74. v-if="isTime && isMinute">
  75. <view
  76. class="graceDateTime-item"
  77. :style="indicatorStyle"
  78. v-for="(item, index) in sDate[4]"
  79. :key="index">
  80. <text
  81. class="graceDateTime-item gui-block-text"
  82. :style="indicatorStyle">{{item}}{{units[4]}}</text>
  83. </view>
  84. </picker-view-column>
  85. <picker-view-column
  86. v-if="isTime && isMinute && isSecond">
  87. <view
  88. class="graceDateTime-item"
  89. :style="indicatorStyle"
  90. v-for="(item, index) in sDate[5]"
  91. :key="index">
  92. <text
  93. class="graceDateTime-item gui-block-text"
  94. :style="indicatorStyle">{{item}}{{units[5]}}</text>
  95. </view>
  96. </picker-view-column>
  97. </picker-view>
  98. </view>
  99. </view>
  100. </view>
  101. </template>
  102. <script>
  103. export default {
  104. name : "gui-datetime",
  105. props : {
  106. cancelText : { type : String, default : '取消' },
  107. cancelTColor : { type : String, default : '#888888' },
  108. confirmText : { type : String, default : '确定' },
  109. confirmColor : { type : String, default : '#008AFF' },
  110. value : { type : String , default : ''},
  111. isTime : { type : Boolean, default : true},
  112. isMinute : { type : Boolean, default : true},
  113. isSecond : { type : Boolean, default : true},
  114. startYear : { type : Number, default : 1980},
  115. endYear : { type : Number, default : 2050},
  116. units : { type : Array , default : function(){return new Array('年','月','日','时','分','秒')}},
  117. height : { type : String, default : '300rpx' },
  118. zIndex : { type : Number, default : 90},
  119. width : { type : String, default : '750rpx' },
  120. indicatorStyle : { type : String, default : 'height:36px; line-height:36px;'}
  121. },
  122. data() {
  123. return {
  124. show:false,
  125. defaultVal : [0,0,0,0,0,0],
  126. sDate:[[],[],[],[],[],[]],
  127. timer:null,
  128. show : false
  129. }
  130. },
  131. created() {
  132. this.init();
  133. },
  134. methods: {
  135. stopfun:function(e){e.stopPropagation(); return ;},
  136. now : function () {
  137. var date = new Date();
  138. var y = date.getFullYear();
  139. var m = date.getMonth() + 1;
  140. m = m < 10 ? ('0' + m) : m;
  141. var d = date.getDate();
  142. d = d < 10 ? ('0' + d) : d;
  143. var h = date.getHours();
  144. h = h < 10 ? ('0' + h) : h;
  145. var minute = date.getMinutes();
  146. var second = date.getSeconds();
  147. minute = minute < 10 ? ('0' + minute) : minute;
  148. second = second < 10 ? ('0' + second) : second;
  149. return y + '-' + m + '-' + d + ' '+ h +':' + minute + ':' + second;
  150. },
  151. arrayIndexOf : function(arr, needFind){
  152. var index = -1;
  153. for(let i = 0; i < arr.length; i++){if(arr[i] == needFind){index = i; return i;}}
  154. return index;
  155. },
  156. setValue : function (val) {
  157. if(val == ''){val = this.now();}
  158. var reg = /^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/;
  159. var res = val.match(reg);
  160. if(res == null){
  161. reg = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/;
  162. res = val.match(reg);
  163. if(res == null){
  164. this.setValue(this.now());
  165. return ;
  166. }
  167. res[4] = '00';
  168. res[5] = '00';
  169. res[6] = '00';
  170. }
  171. this.setDefaults([res[1],res[2],res[3],res[4],res[5],res[6]]);
  172. },
  173. setDefaults : function (res) {
  174. for(let i = 0; i < res.length; i++){
  175. var index = this.arrayIndexOf(this.sDate[i], res[i]);
  176. if(index == -1){index = 0;}
  177. this.defaultVal.splice(i, 1, index);
  178. }
  179. this.changeBase(this.defaultVal);
  180. },
  181. // 初始化组件
  182. init:function(){
  183. if(this.endYear < this.startYear){this.endYear = this.startYear + 10;}
  184. var years = new Array();
  185. for(let i = this.startYear; i <= this.endYear; i++){years.push(i);}
  186. var months = new Array();
  187. for(let i = 1; i <= 12; i++){if(i < 10){months.push('0'+i);}else{months.push(i);}}
  188. var days = new Array();
  189. for(let i = 1; i <= 31; i++){if(i < 10){days.push('0'+i);}else{days.push(i);}}
  190. var hours = new Array();
  191. for(let i = 0; i < 24; i++){if(i < 10){hours.push('0'+i);}else{hours.push(i);}}
  192. var minutes = new Array();
  193. var seconds = new Array();
  194. for(let i = 0; i < 60; i++){
  195. if(i < 10){minutes.push('0'+i); seconds.push('0'+i);}else{minutes.push(i); seconds.push(i);}
  196. }
  197. this.sDate = [years, months, days, hours, minutes, seconds];
  198. this.$nextTick(()=>{setTimeout(()=>{ this.setValue(this.value);}, 500);});
  199. },
  200. change : function (res) {
  201. if(this.timer != null){clearTimeout(this.timer);}
  202. this.timer = setTimeout(()=>{this.changeBase(res.detail.value);},500);
  203. },
  204. changeBase:function(res){
  205. var date = new Date(this.sDate[0][res[0]], this.sDate[1][res[1]], 0);
  206. var days = date.getDate();
  207. var daysOut = new Array();
  208. for(let i = 1; i <= days; i++){if(i < 10){daysOut.push('0'+i);}else{daysOut.push(i);}}
  209. this.sDate.splice(2, 1, daysOut);
  210. if(res[2] + 1 > days){res[2] = days - 1;}
  211. this.defaultVal = res;
  212. if(this.isTime){
  213. var resdata = new Array(this.sDate[0][this.defaultVal[0]],
  214. this.sDate[1][this.defaultVal[1]],
  215. this.sDate[2][this.defaultVal[2]],
  216. this.sDate[3][this.defaultVal[3]],
  217. this.sDate[4][this.defaultVal[4]],
  218. this.sDate[5][this.defaultVal[5]]);
  219. }else{
  220. var resdata = new Array(
  221. this.sDate[0][this.defaultVal[0]],
  222. this.sDate[1][this.defaultVal[1]],
  223. this.sDate[2][this.defaultVal[2]]
  224. )
  225. }
  226. this.$emit('change', resdata);
  227. },
  228. confirm:function () {
  229. if(this.isTime){
  230. var res = new Array(this.sDate[0][this.defaultVal[0]],
  231. this.sDate[1][this.defaultVal[1]],
  232. this.sDate[2][this.defaultVal[2]],
  233. this.sDate[3][this.defaultVal[3]],
  234. this.sDate[4][this.defaultVal[4]],
  235. this.sDate[5][this.defaultVal[5]]);
  236. }else{
  237. var res = new Array(this.sDate[0][this.defaultVal[0]],
  238. this.sDate[1][this.defaultVal[1]],
  239. this.sDate[2][this.defaultVal[2]])
  240. }
  241. this.$emit('confirm', res);
  242. this.close();
  243. },
  244. open : function () {
  245. this.show = true;
  246. },
  247. close : function () {
  248. this.show = false;
  249. }
  250. }
  251. }
  252. </script>
  253. <style scoped>
  254. .gui-dateBT-shade{width:750rpx; position:fixed; background-color:rgba(0,0,0,0.5); z-index:99; left:0; top:0; bottom:0; flex:1; overflow:hidden;}
  255. .graceDateTime-header{padding:25rpx;}
  256. .graceDateTime-header-btn{width:200rpx; line-height:38rpx; height:38rpx; font-size:28rpx;}
  257. .graceDateTime-main{width:750rpx; color:#232323;}
  258. .graceDateTime-item{height:36px; font-size:26rpx; line-height:36px; overflow:hidden; text-align:center;}
  259. /* #ifndef APP-NVUE */
  260. .graceDateTime-item{display:block; width:100%;}
  261. /* #endif */
  262. </style>