z-time-select.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <template>
  2. <view class="mask" @touchmove.stop.prevent="moveHandle" v-if="visible">
  3. <view class="picker-view shadow-2" :animation="animation">
  4. <view class="flex-n fac fjb plr-40 ptb-20">
  5. <view class="cancel" @click="cancel">取消</view>
  6. <view class="ok" @click="ok">确定</view>
  7. </view>
  8. <picker-view class="picker-view-content" :value="timevalue" @change="bindChange">
  9. <picker-view-column>
  10. <view class="item" v-for="(item,index) in timeList" :key="index">{{item.hourstext}}</view>
  11. </picker-view-column>
  12. <picker-view-column v-if="timeList&&timeList[oneId]&&timeList[oneId].minutesList">
  13. <view class="item" v-for="(item,index) in timeList[oneId].minutesList" :key="index">{{item}}</view>
  14. </picker-view-column>
  15. </picker-view>
  16. </view>
  17. </view>
  18. </template>
  19. <script>
  20. export default {
  21. name: 'z-time-select',
  22. props: {
  23. value: String|Number,
  24. visible: Boolean,
  25. step: {
  26. type: Number,
  27. default: 1
  28. }, //步长
  29. start: {
  30. type: String,
  31. default: '00:00'
  32. }, //开始时间
  33. end: {
  34. type: String,
  35. default: '24:00'
  36. }, //结束时间
  37. minTime: {
  38. type: String,
  39. default: ''
  40. }, //最小时间,大于不包含
  41. maxTime: {
  42. type: String,
  43. default: ''
  44. }, //最大时间,小于不包含
  45. },
  46. model: {
  47. prop: 'value',
  48. event: 'input'
  49. },
  50. data() {
  51. return {
  52. timeList: [],
  53. oneId: 0,
  54. secondId: 0,
  55. timevalue: [0, 0],
  56. animation: {},
  57. animate: '',
  58. }
  59. },
  60. watch: {
  61. visible(newval, oldval) {
  62. if (newval) {
  63. this.getTimeList();
  64. this.getChecked();
  65. this.animation = this.animate.translateY(500).step({
  66. duration: 0
  67. }).translateY(0).step().export();
  68. }
  69. }
  70. },
  71. mounted() {
  72. this.animate = uni.createAnimation({
  73. duration: 500,
  74. timingFunction: 'ease',
  75. })
  76. },
  77. methods: {
  78. moveHandle() {},
  79. getChecked(){
  80. if(this.value){
  81. var value=this.value.split(':');
  82. for(var i in this.timeList){
  83. if(this.timeList[i].hours==value[0]){
  84. this.timevalue.splice(0,1,Number(i));
  85. this.oneId=i;
  86. for(var j in this.timeList[i].minutesList){
  87. if(this.timeList[i].minutesList[j]==value[1]){
  88. this.timevalue.splice(1,1,Number(j));
  89. this.secondId=j;
  90. break;
  91. }
  92. }
  93. break;
  94. }
  95. }
  96. }
  97. },
  98. getTimeList() {
  99. //有最大最小时间 就执行最大最小时间加减步长,没有就是默认开始结束
  100. var start = this.minTime ? this.minTime.split(':') : this.start.split(':'),
  101. end = this.maxTime ? this.maxTime.split(':') : this.end.split(':'),
  102. step = this.step;
  103. var timeList = [];
  104. var hours = '',
  105. minutes = '';
  106. for (var i = start[0] * 60 + Number(start[1]) + (this.minTime ? this.step : 0); i <= end[0] * 60 + Number(end[1]) -
  107. (this.maxTime ? this.step : 0); i = i + step) {
  108. minutes = i % 60 > 9 ? (i % 60) : ('0' + i % 60);
  109. hours = (i - i % 60) / 60 > 9 ? ((i - i % 60) / 60) : ('0' + ((i - i % 60) / 60));
  110. if (timeList.length > 0 && hours == timeList[timeList.length - 1].hours) {
  111. timeList[timeList.length - 1].minutesList.push(minutes)
  112. } else {
  113. var minutesList = [];
  114. minutesList.push(minutes)
  115. timeList.push({
  116. hours: hours,
  117. hourstext:hours>=24?('次日'+((hours-24)>9?(hours-24):('0'+(hours-24)))):hours,
  118. minutesList: minutesList
  119. })
  120. }
  121. }
  122. console.log(timeList)
  123. this.timeList = timeList;
  124. },
  125. bindChange(e) {
  126. console.log(e.detail.value)
  127. if (this.oneId != e.detail.value[0]) {
  128. this.secondId = 0;
  129. this.oneId = e.detail.value[0];
  130. } else {
  131. this.secondId = e.detail.value[1];
  132. }
  133. this.timevalue = [this.oneId, this.secondId];
  134. },
  135. ok() {
  136. let time=this.timeList[this.oneId].hours+':'+this.timeList[this.oneId].minutesList[this.secondId];
  137. this.$emit('input',time)
  138. this.$emit('update:visible', false);
  139. this.$emit('ok',{
  140. time:time,
  141. text:this.$Date.getFormatTimeText(time)
  142. });
  143. },
  144. cancel() {
  145. this.$emit('cancel');
  146. this.$emit('update:visible', false)
  147. }
  148. }
  149. }
  150. </script>
  151. <style scoped lang="scss">
  152. .mask {
  153. position: fixed;
  154. top: 0;
  155. left: 0;
  156. z-index: 999;
  157. width: 100%;
  158. height: 100vh;
  159. background: rgba($color: #000000, $alpha: 0.3);
  160. }
  161. .picker-view {
  162. position: fixed;
  163. bottom: 0;
  164. left: 0;
  165. width: 100%;
  166. height: 476rpx;
  167. border-top-left-radius: 40rpx;
  168. border-top-right-radius: 40rpx;
  169. overflow: hidden;
  170. background-color: white;
  171. z-index: 666;
  172. .cancel {
  173. font-size: 38rpx;
  174. color: #ccc;
  175. }
  176. .ok {
  177. font-size: 38rpx;
  178. color: #F0AD4E;
  179. }
  180. .picker-view-content {
  181. height: 350rpx;
  182. }
  183. .disabled {
  184. background: #eeeeee;
  185. color: white;
  186. }
  187. .item {
  188. text-align: center;
  189. font-size: 32rpx;
  190. line-height: 64rpx;
  191. }
  192. }
  193. </style>