index.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <template>
  2. <view v-if="date" class="count-down">
  3. <view :class="[`${theme}-theme`, `separator-${separator}`]">
  4. <!-- <block v-if="dynamic.day != '00'">
  5. <text class="dynamic-value">{{ dynamic.day }}</text>
  6. <text class="separator">{{ separatorText.day }}</text>
  7. </block> -->
  8. <block v-if="dynamic.day > 0">
  9. <text class="dynamic-value">{{ dynamic.day }}</text>
  10. <text class="separator">{{ separatorText.day }}</text>
  11. </block>
  12. <text class="dynamic-value" :style="{ backgroundColor: customBgColor }">{{ dynamic.hou }}</text>
  13. <text class="separator">{{ separatorText.hou }}</text>
  14. <text class="dynamic-value" :style="{ backgroundColor: customBgColor }">{{ dynamic.min }}</text>
  15. <text class="separator">{{ separatorText.min }}</text>
  16. <text class="dynamic-value" :style="{ backgroundColor: customBgColor }">{{ dynamic.sec }}</text>
  17. <text class="separator">{{ separatorText.sec }}</text>
  18. </view>
  19. </view>
  20. </template>
  21. <script>
  22. import { formatDate } from '@/utils/util';
  23. export default {
  24. props: {
  25. // 截止的时间
  26. date: {
  27. type: String,
  28. default: ''
  29. },
  30. // 分隔符, colon为英文冒号,zh为中文
  31. separator: {
  32. type: String,
  33. default: 'zh'
  34. },
  35. // 组件主题样式, text为纯文本,custom为带背景色
  36. theme: {
  37. type: String,
  38. default: 'text'
  39. },
  40. // custom样式的背景色
  41. customBgColor: {
  42. type: String,
  43. default: '#252525'
  44. }
  45. },
  46. data() {
  47. return {
  48. // 倒计时数据
  49. dynamic: {
  50. day: '0',
  51. hou: '00',
  52. min: '00',
  53. sec: '00'
  54. },
  55. // 分隔符文案
  56. separatorText: {
  57. day: '天',
  58. hou: '时',
  59. min: '分',
  60. sec: '秒'
  61. }
  62. };
  63. },
  64. created() {
  65. // 分隔符文案
  66. this.setSeparatorText();
  67. // 开始倒计时
  68. this.onTime();
  69. },
  70. methods: {
  71. // 分隔符文案
  72. setSeparatorText() {
  73. const sText = this.separatorText;
  74. if (this.separator === 'colon') {
  75. sText.day = ':'
  76. sText.hou = sText.min = ':'
  77. sText.sec = ''
  78. }
  79. this.separatorText = sText
  80. },
  81. // 开始倒计时
  82. onTime(deep = 0) {
  83. const app = this;
  84. const dynamic = {};
  85. // 获取当前时间,同时得到活动结束时间数组
  86. const newTime = new Date().getTime();
  87. // 对结束时间进行处理渲染到页面
  88. const endTime = new Date(formatDate(app.date)).getTime();
  89. // 如果活动未结束,对时间进行处理
  90. if (endTime - newTime <= 0) {
  91. return false;
  92. }
  93. const diffTime = (endTime - newTime) / 1000;
  94. // 获取时、分、秒
  95. const day = parseInt(diffTime / 86400),
  96. hou = parseInt((diffTime % 86400) / 3600),
  97. min = parseInt(((diffTime % 86400) % 3600) / 60),
  98. sec = parseInt(((diffTime % 86400) % 3600) % 60);
  99. dynamic.day = day;
  100. dynamic.hou = app.timeFormat(hou);
  101. dynamic.min = app.timeFormat(min);
  102. dynamic.sec = app.timeFormat(sec);
  103. // 渲染,然后每隔一秒执行一次倒计时函数
  104. app.dynamic = dynamic;
  105. // 判断倒计时是否结束
  106. const isEnd = app.isEnd();
  107. // 结束后执行回调函数
  108. if (isEnd) {
  109. deep > 0 && app.$emit('finish');
  110. }
  111. // 重复执行
  112. if (!isEnd) {
  113. setTimeout(() => {
  114. app.onTime(++deep);
  115. }, 100);
  116. }
  117. },
  118. // 判断倒计时是否结束
  119. isEnd() {
  120. const { dynamic } = this;
  121. return dynamic.day == '00' && dynamic.hou == '00' && dynamic.min == '00' && dynamic.sec == '00';
  122. },
  123. // 小于10的格式化函数
  124. timeFormat(value) {
  125. return value < 10 ? '0' + value : value;
  126. }
  127. }
  128. };
  129. </script>
  130. <style lang="scss" scoped>
  131. .item {
  132. display: inline-block;
  133. width: 22px;
  134. margin-right: 5px;
  135. color: #fff;
  136. font-size: 12px;
  137. text-align: center;
  138. background-color: #1989fa;
  139. border-radius: 2px;
  140. }
  141. .separator {
  142. padding: 0 2rpx;
  143. }
  144. // 纯文本主题
  145. .text-theme {
  146. // 冒号分隔符
  147. .separator-colon .separator {
  148. padding: 0 5rpx;
  149. }
  150. .dynamic-value {
  151. background: none !important;
  152. }
  153. }
  154. // 背景主题
  155. .custom-theme {
  156. .dynamic-value {
  157. background: #252525;
  158. color: #fff;
  159. padding: 2rpx 8rpx;
  160. line-height: 40rpx;
  161. border-radius: 8rpx;
  162. }
  163. .separator {
  164. padding: 0 6rpx;
  165. }
  166. }
  167. </style>