index.js 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { VantComponent } from '../common/component';
  2. import { isSameSecond, parseFormat, parseTimeData } from './utils';
  3. function simpleTick(fn) {
  4. return setTimeout(fn, 30);
  5. }
  6. VantComponent({
  7. props: {
  8. useSlot: Boolean,
  9. millisecond: Boolean,
  10. time: {
  11. type: Number,
  12. observer: 'reset',
  13. },
  14. format: {
  15. type: String,
  16. value: 'HH:mm:ss',
  17. },
  18. autoStart: {
  19. type: Boolean,
  20. value: true,
  21. },
  22. },
  23. data: {
  24. timeData: parseTimeData(0),
  25. formattedTime: '0',
  26. },
  27. destroyed() {
  28. clearTimeout(this.tid);
  29. this.tid = null;
  30. },
  31. methods: {
  32. // 开始
  33. start() {
  34. if (this.counting) {
  35. return;
  36. }
  37. this.counting = true;
  38. this.endTime = Date.now() + this.remain;
  39. this.tick();
  40. },
  41. // 暂停
  42. pause() {
  43. this.counting = false;
  44. clearTimeout(this.tid);
  45. },
  46. // 重置
  47. reset() {
  48. this.pause();
  49. this.remain = this.data.time;
  50. this.setRemain(this.remain);
  51. if (this.data.autoStart) {
  52. this.start();
  53. }
  54. },
  55. tick() {
  56. if (this.data.millisecond) {
  57. this.microTick();
  58. }
  59. else {
  60. this.macroTick();
  61. }
  62. },
  63. microTick() {
  64. this.tid = simpleTick(() => {
  65. this.setRemain(this.getRemain());
  66. if (this.remain !== 0) {
  67. this.microTick();
  68. }
  69. });
  70. },
  71. macroTick() {
  72. this.tid = simpleTick(() => {
  73. const remain = this.getRemain();
  74. if (!isSameSecond(remain, this.remain) || remain === 0) {
  75. this.setRemain(remain);
  76. }
  77. if (this.remain !== 0) {
  78. this.macroTick();
  79. }
  80. });
  81. },
  82. getRemain() {
  83. return Math.max(this.endTime - Date.now(), 0);
  84. },
  85. setRemain(remain) {
  86. this.remain = remain;
  87. const timeData = parseTimeData(remain);
  88. if (this.data.useSlot) {
  89. this.$emit('change', timeData);
  90. }
  91. this.setData({
  92. formattedTime: parseFormat(this.data.format, timeData),
  93. });
  94. if (remain === 0) {
  95. this.pause();
  96. this.$emit('finish');
  97. }
  98. },
  99. },
  100. });