index.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <template>
  2. <view v-if="date" class="count-down" :style="{ color: textColor, fontSize: `${fontSize}rpx` }">
  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" :style="{ backgroundColor: customNumBgColor, color: customNumColor }">{{ dynamic.day }}</text>
  10. <text class="separator day">{{ separatorText.day }}</text>
  11. </block>
  12. <text class="dynamic-value" :style="{ backgroundColor: customNumBgColor, color: customNumColor }">{{ dynamic.hou }}</text>
  13. <text class="separator">{{ separatorText.hou }}</text>
  14. <text class="dynamic-value" :style="{ backgroundColor: customNumBgColor, color: customNumColor }">{{ dynamic.min }}</text>
  15. <text class="separator">{{ separatorText.min }}</text>
  16. <text class="dynamic-value" :style="{ backgroundColor: customNumBgColor, color: customNumColor }">{{ 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. textColor: {
  42. type: String,
  43. default: '#303133'
  44. },
  45. fontSize: {
  46. type: Number,
  47. default: 26
  48. },
  49. // custom: 倒计时数字背景颜色
  50. customNumBgColor: {
  51. type: String,
  52. default: '#252525'
  53. },
  54. // custom: 倒计时数字颜色
  55. customNumColor: {
  56. type: String,
  57. default: '#fff'
  58. },
  59. },
  60. data() {
  61. return {
  62. // 倒计时数据
  63. dynamic: {
  64. day: '0',
  65. hou: '00',
  66. min: '00',
  67. sec: '00'
  68. },
  69. // 分隔符文案
  70. separatorText: {
  71. day: '天',
  72. hou: '时',
  73. min: '分',
  74. sec: '秒'
  75. }
  76. };
  77. },
  78. created() {
  79. // 分隔符文案
  80. this.setSeparatorText();
  81. // 开始倒计时
  82. this.onTime();
  83. },
  84. methods: {
  85. // 分隔符文案
  86. setSeparatorText() {
  87. const sText = this.separatorText;
  88. if (this.separator === 'colon') {
  89. sText.day = '天'
  90. sText.hou = sText.min = ':'
  91. sText.sec = ''
  92. }
  93. this.separatorText = sText
  94. },
  95. // 开始倒计时
  96. onTime(deep = 0) {
  97. const app = this;
  98. const dynamic = {};
  99. // 获取当前时间,同时得到活动结束时间数组
  100. const newTime = new Date().getTime();
  101. // 对结束时间进行处理渲染到页面
  102. const endTime = new Date(formatDate(app.date)).getTime();
  103. // 如果活动未结束,对时间进行处理
  104. if (endTime - newTime <= 0) {
  105. return false;
  106. }
  107. const diffTime = (endTime - newTime) / 1000;
  108. // 获取时、分、秒
  109. const day = parseInt(diffTime / 86400),
  110. hou = parseInt((diffTime % 86400) / 3600),
  111. min = parseInt(((diffTime % 86400) % 3600) / 60),
  112. sec = parseInt(((diffTime % 86400) % 3600) % 60);
  113. dynamic.day = day;
  114. dynamic.hou = app.timeFormat(hou);
  115. dynamic.min = app.timeFormat(min);
  116. dynamic.sec = app.timeFormat(sec);
  117. // 渲染,然后每隔一秒执行一次倒计时函数
  118. app.dynamic = dynamic;
  119. // 判断倒计时是否结束
  120. const isEnd = app.isEnd();
  121. // 结束后执行回调函数
  122. if (isEnd) {
  123. deep > 0 && app.$emit('finish');
  124. }
  125. // 重复执行
  126. if (!isEnd) {
  127. setTimeout(() => {
  128. app.onTime(++deep);
  129. }, 100);
  130. }
  131. },
  132. // 判断倒计时是否结束
  133. isEnd() {
  134. const { dynamic } = this;
  135. return dynamic.day == '00' && dynamic.hou == '00' && dynamic.min == '00' && dynamic.sec == '00';
  136. },
  137. // 小于10的格式化函数
  138. timeFormat(value) {
  139. return value < 10 ? '0' + value : value;
  140. }
  141. }
  142. };
  143. </script>
  144. <style lang="scss" scoped>
  145. .count-down {
  146. font-size: 26rpx;
  147. }
  148. // 分隔符
  149. .separator {
  150. padding: 0 2rpx;
  151. }
  152. // 纯文本主题
  153. .text-theme {
  154. // 冒号分隔符
  155. .separator-colon .separator {
  156. padding: 0 5rpx;
  157. }
  158. .dynamic-value {
  159. background: none !important;
  160. }
  161. }
  162. // 背景主题
  163. .custom-theme {
  164. .dynamic-value {
  165. display: inline-block;
  166. background: #252525;
  167. width: 40rpx;
  168. height: 40rpx;
  169. line-height: 40rpx;
  170. text-align: center;
  171. border-radius: 8rpx;
  172. color: #fff;
  173. }
  174. .separator {
  175. padding: 0 10rpx;
  176. &.day {
  177. padding: 0 8rpx;
  178. }
  179. }
  180. }
  181. </style>