电速宝
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

index.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. Component({
  2. properties: {
  3. // 是否显示弹窗
  4. isShow: {
  5. type: Boolean,
  6. value: false
  7. },
  8. // 手机号(用于显示)
  9. phoneNumber: {
  10. type: String,
  11. value: ''
  12. },
  13. // 倒计时秒数
  14. countdownSeconds: {
  15. type: Number,
  16. value: 120
  17. }
  18. },
  19. data: {
  20. // 验证码数组(6位)
  21. codes: ['', '', '', ''],
  22. // 实际输入的验证码值
  23. codeValue: '',
  24. // 当前激活的输入框索引
  25. currentIndex: 0,
  26. // 是否聚焦
  27. isFocus: false,
  28. // 倒计时
  29. countdown: 120,
  30. // 是否可以重新发送
  31. canResend: false,
  32. // 验证码是否输入完成
  33. isComplete: false,
  34. // 倒计时计时器
  35. timer: null
  36. },
  37. observers: {
  38. // 监听isShow变化,控制弹窗显示隐藏
  39. isShow: function (isShow) {
  40. if (isShow) {
  41. this.startCountdown();
  42. this.focusInput();
  43. } else {
  44. this.clearCountdown();
  45. this.resetCodeInput();
  46. }
  47. },
  48. // 监听countdownSeconds变化
  49. countdownSeconds: function (seconds) {
  50. this.setData({
  51. countdown: seconds
  52. });
  53. },
  54. // 监听验证码变化,更新输入状态
  55. codeValue: function (value) {
  56. const codes = [];
  57. for (let i = 0; i < 4; i++) {
  58. codes[i] = value[i] || '';
  59. }
  60. // 更新当前激活的输入框索引
  61. let currentIndex = value.length < 4 ? value.length : 3;
  62. // 判断是否输入完成
  63. const isComplete = value.length === 4;
  64. this.setData({
  65. codes,
  66. currentIndex,
  67. isComplete
  68. });
  69. // 如果输入完成,自动触发确认事件
  70. if (isComplete) {
  71. this.triggerEvent('complete', { code: value });
  72. }
  73. }
  74. },
  75. methods: {
  76. // 聚焦输入框
  77. focusInput() {
  78. this.setData({
  79. isFocus: true
  80. });
  81. },
  82. // 输入框失焦
  83. onInputBlur() {
  84. this.setData({
  85. isFocus: false
  86. });
  87. },
  88. // 验证码输入
  89. onCodeInput(e) {
  90. const value = e.detail.value.replace(/\D/g, ''); // 只保留数字
  91. this.setData({
  92. codeValue: value
  93. });
  94. },
  95. // 关闭弹窗
  96. onClose() {
  97. // 1. 强制让输入框失焦,关闭手机键盘
  98. this.setData({ isFocus: false });
  99. // 2. 触发关闭事件(可加微延时确保失焦生效,可选)
  100. setTimeout(() => {
  101. this.triggerEvent('close');
  102. }, 100);
  103. // this.triggerEvent('close');
  104. },
  105. // 确认
  106. onConfirm() {
  107. if (this.data.isComplete) {
  108. this.triggerEvent('confirm', { code: this.data.codeValue });
  109. }
  110. },
  111. // 重新发送验证码
  112. onResend() {
  113. this.triggerEvent('resend');
  114. this.startCountdown();
  115. },
  116. // 开始倒计时
  117. startCountdown() {
  118. // 清除之前的计时器
  119. this.clearCountdown();
  120. const countdownSeconds = this.data.countdownSeconds;
  121. this.setData({
  122. countdown: countdownSeconds,
  123. canResend: false
  124. });
  125. // 设置新的计时器
  126. const timer = setInterval(() => {
  127. let countdown = this.data.countdown - 1;
  128. if (countdown <= 0) {
  129. this.setData({
  130. countdown: 0,
  131. canResend: true
  132. });
  133. this.clearCountdown();
  134. } else {
  135. this.setData({
  136. countdown
  137. });
  138. }
  139. }, 1000);
  140. this.setData({ timer });
  141. },
  142. // 清除倒计时
  143. clearCountdown() {
  144. this.setData({ isFocus: false });
  145. if (this.data.timer) {
  146. clearInterval(this.data.timer);
  147. this.setData({ timer: null });
  148. }
  149. },
  150. // 重置验证码输入
  151. resetCodeInput() {
  152. this.setData({
  153. codes: ['', '', '', '', '', ''],
  154. codeValue: '',
  155. currentIndex: 0,
  156. isComplete: false
  157. });
  158. }
  159. },
  160. // 组件销毁时清除计时器
  161. detached() {
  162. this.clearCountdown();
  163. }
  164. });