count-down.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <template>
  2. <view class="aaa-count-down" :class="theme">
  3. <view :class="'wrap-'+theme" v-if="isShow">
  4. <view class="before" v-if="isBefore">{{before}}</view>
  5. <view class="day" v-if="time.day > 0">
  6. <text>{{time.day}}</text>
  7. <text>{{dayText}}</text>
  8. </view>
  9. <view class="hour">
  10. <text>{{time.hour}}</text>
  11. <text>{{hourText}}</text>
  12. </view>
  13. <view class="minute">
  14. <text>{{time.minute}}</text>
  15. <text>{{minuteText}}</text>
  16. </view>
  17. <view class="second">
  18. <text>{{time.second}}</text>
  19. <text>{{secondText}}</text>
  20. </view>
  21. <view class="after" v-if="after">{{after}}</view>
  22. </view>
  23. <view v-if="!isShow" :class="'tips-'+theme">{{tips}}</view>
  24. </view>
  25. </template>
  26. <script>
  27. export default {
  28. name: "CountDown",
  29. props: {
  30. nowTime: {
  31. type: [String,Number],
  32. default: "0"
  33. },
  34. startTime: {
  35. type: [String,Number],
  36. default: "0"
  37. },
  38. endTime: {
  39. type: [String,Number],
  40. default: "0"
  41. },
  42. startTexts: {
  43. type: String,
  44. default: "距开始仅剩:"
  45. },
  46. endTexts: {
  47. type: String,
  48. default: "距结束仅剩:"
  49. },
  50. finishTexts: {
  51. type: String,
  52. default: "活动已结束"
  53. },
  54. dayText: {
  55. type: String,
  56. default: "天"
  57. },
  58. hourText: {
  59. type: String,
  60. default: "小时"
  61. },
  62. minuteText: {
  63. type: String,
  64. default: "分"
  65. },
  66. secondText: {
  67. type: String,
  68. default: "秒"
  69. },
  70. theme: {
  71. type: String,
  72. default: "simple"
  73. },
  74. isBefore: {
  75. type: Boolean,
  76. default: false
  77. },
  78. fillZero: {
  79. type: Object,
  80. default: function () {
  81. return {
  82. day : { count : 86400, num : 2, def : '00' },
  83. hour : { count : 3600, num : 2, def : '00' },
  84. minute : { count : 60, num : 2, def : '00' },
  85. second : { count : 1 , num : 2, def : '00' }
  86. }
  87. }
  88. }
  89. },
  90. data(){
  91. return {
  92. time: {
  93. day: "",
  94. hour: "",
  95. minute: "",
  96. second: ""
  97. },
  98. before: "",
  99. after: "",
  100. current: 0,
  101. start: 0,
  102. end: 0,
  103. total: 0,
  104. tips: "",
  105. isShow: false,
  106. timer: null
  107. };
  108. },
  109. watch: {
  110. endTime: {
  111. handler(newValue) {
  112. this.run();
  113. },
  114. immediate: true
  115. }
  116. },
  117. methods: {
  118. run(){
  119. if(this.nowTime == undefined || this.startTime == undefined || this.endTime == undefined){
  120. return ;
  121. }
  122. this.now = this.nowTime;
  123. this.start = this.startTime;
  124. this.end = this.endTime;
  125. this.total = this.end - this.now;
  126. this.updateStatus(false);
  127. this.message(false,"");
  128. if(this.total <= 0){
  129. this.message(false,this.finishTexts);
  130. return ;
  131. }else if(this.nowTime < this.startTime){
  132. this.before = this.startTexts;
  133. }else if(this.nowTime > this.startTime && this.endTime > this.nowTime){
  134. this.before = this.endTexts;
  135. this.updateStatus(true);
  136. }
  137. this.timer = setInterval(()=>{
  138. this.runTime();
  139. },1000);
  140. },
  141. runTime(){
  142. if(this.total <= 0){
  143. this.timer && clearInterval(this.timer);
  144. this.message(false,this.finishText);
  145. this.updateStatus(false);
  146. return ;
  147. }
  148. let dateTime = this.total;
  149. for(let i in this.fillZero){
  150. let data = this.fillZero[i];
  151. let flag = dateTime >= data.count ? true : false;
  152. if(!flag){
  153. this.time[i] = data.def;
  154. }
  155. if(flag){
  156. let value = Math.floor(dateTime / data.count);
  157. this.time[i] = this.fill(value.toString(),data.num);
  158. dateTime -= value * data.count;
  159. }
  160. }
  161. this.total--;
  162. this.message(true);
  163. },
  164. fill(i,n){
  165. let str = '' + i;
  166. while(str.length < n){
  167. str = '0' + str;
  168. }
  169. return str;
  170. },
  171. message(status,msg){
  172. this.tips = msg || "";
  173. this.isShow = status;
  174. },
  175. updateStatus(status){
  176. this.$emit("update:status",status);
  177. }
  178. }
  179. }
  180. </script>
  181. <style>
  182. .aaa-count-down .day,
  183. .aaa-count-down .hour,
  184. .aaa-count-down .minute,
  185. .aaa-count-down .second,
  186. .aaa-count-down .day,
  187. .aaa-count-down .day { float: left; }
  188. </style>