countdown.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <template>
  2. <view class="tui-countdown-box">
  3. <view class="tui-countdown-item" :style="{background:bgcolor,borderColor:bcolor,width:width+'rpx',height:height+'rpx'}"
  4. v-if="days">
  5. <view class="tui-countdown-time" :class="[scale?'tui-countdown-scale':'']" :style="{fontSize:size+'rpx',color:color,lineHeight:size +'rpx'}">{{d}}</view>
  6. </view>
  7. <view class="tui-countdown-colon" :class="{'tui-colon-pad':bcolor=='transparent'}" :style="{lineHeight:colonSize+'rpx',fontSize:colonSize+'rpx',color:colonColor}"
  8. v-if="days">{{isColon?':':'天'}}</view>
  9. <view class="tui-countdown-item" :style="{background:bgcolor,borderColor:bcolor,width:width+'rpx',height:height+'rpx'}"
  10. v-if="hours">
  11. <view class="tui-countdown-time" :class="[scale?'tui-countdown-scale':'']" :style="{fontSize:size+'rpx',color:color,lineHeight:size +'rpx'}">{{h}}</view>
  12. </view>
  13. <view class="tui-countdown-colon" :class="{'tui-colon-pad':bcolor=='transparent'}" :style="{lineHeight:colonSize+'rpx',fontSize:colonSize+'rpx',color:colonColor}"
  14. v-if="hours">{{isColon?':':'时'}}</view>
  15. <view class="tui-countdown-item" :style="{background:bgcolor,borderColor:bcolor,width:width+'rpx',height:height+'rpx'}"
  16. v-if="minutes">
  17. <view class="tui-countdown-time" :class="[scale?'tui-countdown-scale':'']" :style="{fontSize:size+'rpx',color:color,lineHeight:size +'rpx'}">{{i}}</view>
  18. </view>
  19. <view class="tui-countdown-colon" :class="{'tui-colon-pad':bcolor=='transparent'}" :style="{lineHeight:colonSize+'rpx',fontSize:colonSize+'rpx',color:colonColor}"
  20. v-if="minutes">{{isColon?':':'分'}}</view>
  21. <view class="tui-countdown-item" :style="{background:bgcolor,borderColor:bcolor,width:width+'rpx',height:height+'rpx'}"
  22. v-if="seconds && minutes">
  23. <view class="tui-countdown-time" :class="[scale?'tui-countdown-scale':'']" :style="{fontSize:size+'rpx',color:color,lineHeight:size +'rpx'}">{{s}}</view>
  24. </view>
  25. <view class="tui-countdown-colon" :class="{'tui-colon-pad':bcolor=='transparent'}" :style="{lineHeight:colonSize+'rpx',fontSize:colonSize+'rpx',color:colonColor}"
  26. v-if="seconds && !isColon && minutes">秒</view>
  27. </view>
  28. </template>
  29. <script>
  30. export default {
  31. name: "tuiCountdown",
  32. props: {
  33. //数字框宽度
  34. width: {
  35. type: Number,
  36. default: 24
  37. },
  38. //数字框高度
  39. height: {
  40. type: Number,
  41. default: 24
  42. },
  43. //数字框border颜色
  44. bcolor: {
  45. type: String,
  46. default: "#333"
  47. },
  48. //数字框背景颜色
  49. bgcolor: {
  50. type: String,
  51. default: "#fff"
  52. },
  53. //数字框字体大小
  54. size: {
  55. type: Number,
  56. default: 24
  57. },
  58. //数字框字体颜色
  59. color: {
  60. type: String,
  61. default: "#333"
  62. },
  63. //是否缩放 0.9
  64. scale: {
  65. type: Boolean,
  66. default: false
  67. },
  68. //冒号大小
  69. colonSize: {
  70. type: Number,
  71. default: 28
  72. },
  73. //冒号颜色
  74. colonColor: {
  75. type: String,
  76. default: "#333"
  77. },
  78. //剩余时间 (单位:秒)
  79. time: {
  80. type: Number,
  81. default:0
  82. },
  83. //是否包含天
  84. days: {
  85. type: Boolean,
  86. default: false
  87. },
  88. //是否包含小时
  89. hours: {
  90. type: Boolean,
  91. default: true
  92. },
  93. //是否包含分钟
  94. minutes: {
  95. type: Boolean,
  96. default: true
  97. },
  98. //是否包含秒
  99. seconds: {
  100. type: Boolean,
  101. default: true
  102. },
  103. //是否展示为冒号,false为文字
  104. isColon: {
  105. type: Boolean,
  106. default: true
  107. }
  108. },
  109. data() {
  110. return {
  111. countdown: null,
  112. h: '00',
  113. i: '00',
  114. s: '00'
  115. };
  116. },
  117. watch: {
  118. time(val) {
  119. clearInterval(this.countdown)
  120. this.doLoop()
  121. }
  122. },
  123. data() {
  124. return {
  125. countdown: null,
  126. d: "0",
  127. h: '00',
  128. i: '00',
  129. s: '00'
  130. };
  131. },
  132. created() {
  133. this.doLoop()
  134. },
  135. beforeDestroy() {
  136. clearInterval(this.countdown)
  137. this.countdown = null
  138. },
  139. methods: {
  140. endOfTime() {
  141. clearInterval(this.countdown)
  142. this.countdown = null;
  143. this.$emit('end', {});
  144. },
  145. doLoop: function() {
  146. let seconds = this.time || 0
  147. this.countDown(seconds)
  148. this.countdown = setInterval(() => {
  149. seconds--
  150. if (seconds < 0) {
  151. this.endOfTime()
  152. return
  153. }
  154. this.countDown(seconds)
  155. }, 1000)
  156. },
  157. countDown(seconds) {
  158. let [day, hour, minute, second] = [0, 0, 0, 0]
  159. if (seconds > 0) {
  160. day = this.days ? Math.floor(seconds / (60 * 60 * 24)) : 0
  161. hour = Math.floor(seconds / (60 * 60)) - (day * 24)
  162. minute = Math.floor(seconds / 60) - (hour * 60) - (day * 24 * 60)
  163. second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
  164. } else {
  165. this.endOfTime()
  166. }
  167. hour = hour < 10 ? ('0' + hour) : hour
  168. minute = minute < 10 ? ('0' + minute) : minute
  169. second = second < 10 ? ('0' + second) : second
  170. this.d = day;
  171. this.h = hour;
  172. this.i = minute;
  173. this.s = second
  174. }
  175. }
  176. }
  177. </script>
  178. <style>
  179. .tui-countdown-box {
  180. display: flex;
  181. align-items: center;
  182. }
  183. .tui-countdown-box {
  184. display: flex;
  185. align-items: center;
  186. }
  187. .tui-countdown-item {
  188. border: 1rpx solid;
  189. display: flex;
  190. align-items: center;
  191. justify-content: center;
  192. padding: 1rpx;
  193. border-radius: 6rpx;
  194. white-space: nowrap;
  195. transform: translateZ(0);
  196. }
  197. .tui-countdown-time {
  198. margin: 0;
  199. padding: 0;
  200. }
  201. .tui-countdown-colon {
  202. display: flex;
  203. justify-content: center;
  204. padding: 0 5rpx;
  205. }
  206. .tui-colon-pad {
  207. padding: 0 !important;
  208. }
  209. .tui-countdown-scale {
  210. transform: scale(0.9);
  211. transform-origin: center center;
  212. }
  213. </style>