电速宝
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

index.js 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. Component({
  2. properties: {
  3. isShow: {
  4. type: Boolean,
  5. value: false
  6. },
  7. type: {
  8. type: String,
  9. value: 'code' // 'code' 验证码 / '结算' 结算密码
  10. },
  11. // 新增:外部可配置倒计时总时长(默认60秒)
  12. countdownTotal: {
  13. type: Number,
  14. value: 60
  15. }
  16. },
  17. data: {
  18. codes: [], // 输入框显示的数组
  19. currentIndex: 0, // 当前激活索引
  20. isFocus: false, // 输入框聚焦状态
  21. codeValue: '', // 4位验证码真实值
  22. oncodeValue: '', // 6位结算密码真实值
  23. isShakeError: false, // 晃动动画开关
  24. // 新增:倒计时相关数据
  25. countdown: 0, // 当前剩余倒计时秒数
  26. timer: null // 倒计时定时器(用于清除定时器,防止内存泄漏)
  27. },
  28. // 新增:组件卸载时清除定时器,防止内存泄漏
  29. detached() {
  30. clearInterval(this.data.timer);
  31. },
  32. methods: {
  33. // 关闭弹窗
  34. onClose() {
  35. this.triggerEvent('close');
  36. this.resetInput(); // 关闭时重置输入
  37. this.resetCountdown(); // 关闭时重置倒计时
  38. },
  39. // 聚焦输入框
  40. focusInput() {
  41. this.setData({ isFocus: true });
  42. },
  43. // 输入内容处理
  44. onCodeInput(e) {
  45. console.log(e);
  46. const value = e.detail.value;
  47. const len = this.data.type === '结算' ? 6 : 4;
  48. const codes = value.split('').slice(0, len);
  49. this.setData({
  50. codes: codes,
  51. currentIndex: codes.length,
  52. codeValue: this.data.type !== '结算' ? value : this.data.codeValue,
  53. oncodeValue: this.data.type === '结算' ? value : this.data.oncodeValue
  54. });
  55. // 输入完成:仅传递值给父组件,不做检验
  56. if (codes.length === len) {
  57. const finalValue = this.data.type === '结算' ? this.data.oncodeValue : this.data.codeValue;
  58. // 向父组件发送输入完成的事件,携带输入值
  59. this.triggerEvent('inputComplete', { value: finalValue });
  60. this.setData({ isFocus: false });
  61. }
  62. },
  63. // 输入框失焦
  64. onInputBlur() {
  65. this.setData({ isFocus: false });
  66. },
  67. // 重新发送验证码(仅传递事件给父组件,并启动倒计时)
  68. onResend() {
  69. // 启动倒计时(防止重复点击重复启动定时器)
  70. this.startCountdown();
  71. // 向父组件发送重新发送事件
  72. this.triggerEvent('resend');
  73. },
  74. // 重置输入内容(供父组件/自身调用)
  75. resetInput() {
  76. this.setData({
  77. codes: [],
  78. currentIndex: 0,
  79. codeValue: '',
  80. oncodeValue: ''
  81. });
  82. },
  83. // 触发失败动效(供父组件调用)
  84. triggerErrorShake() {
  85. this.setData({ isShakeError: true });
  86. // 动画结束后重置状态
  87. setTimeout(() => {
  88. this.setData({ isShakeError: false });
  89. }, 500);
  90. // 同时清空输入
  91. this.resetInput();
  92. },
  93. // 新增:启动倒计时
  94. startCountdown() {
  95. // 1. 先清除已有定时器,防止重复创建
  96. clearInterval(this.data.timer);
  97. // 2. 初始化倒计时为总时长
  98. const total = this.data.countdownTotal;
  99. this.setData({
  100. countdown: total
  101. });
  102. // 3. 创建定时器,每秒更新倒计时
  103. const timer = setInterval(() => {
  104. this.setData({
  105. countdown: this.data.countdown - 1
  106. }, () => {
  107. // 4. 倒计时结束后清除定时器,重置倒计时状态
  108. if (this.data.countdown <= 0) {
  109. clearInterval(this.data.timer);
  110. this.resetCountdown();
  111. }
  112. });
  113. }, 1000);
  114. // 5. 保存定时器实例,用于后续清除
  115. this.setData({ timer });
  116. },
  117. // 新增:重置倒计时(恢复初始状态)
  118. resetCountdown() {
  119. clearInterval(this.data.timer);
  120. this.setData({
  121. countdown: 0,
  122. timer: null
  123. });
  124. }
  125. }
  126. });