index.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. } else {
  59. this.macroTick();
  60. }
  61. },
  62. microTick() {
  63. this.tid = simpleTick(() => {
  64. this.setRemain(this.getRemain());
  65. if (this.remain !== 0) {
  66. this.microTick();
  67. }
  68. });
  69. },
  70. macroTick() {
  71. this.tid = simpleTick(() => {
  72. const remain = this.getRemain();
  73. if (!isSameSecond(remain, this.remain) || remain === 0) {
  74. this.setRemain(remain);
  75. }
  76. if (this.remain !== 0) {
  77. this.macroTick();
  78. }
  79. });
  80. },
  81. getRemain() {
  82. return Math.max(this.endTime - Date.now(), 0);
  83. },
  84. setRemain(remain) {
  85. this.remain = remain;
  86. const timeData = parseTimeData(remain);
  87. if (this.data.useSlot) {
  88. this.$emit('change', timeData);
  89. }
  90. this.setData({
  91. formattedTime: parseFormat(this.data.format, timeData),
  92. });
  93. if (remain === 0) {
  94. this.pause();
  95. this.$emit('finish');
  96. }
  97. },
  98. },
  99. });