gui-datetime.vue 12 KB

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