微信输入手机号,验证码

440 阅读1分钟

image.png

如上图,想实现输入注册手机号,及6位数字验证码。并且输入后倒计时60秒 主要分为 wxml,wxss,js 三块。 其中用到的倒计时模块,单独写成工具类使用。

toast 是一个提示工具类,详见我另外一篇文章: juejin.cn/post/700513…

wxml

  <block>
    <view class="section-title">注册手机号</view>
    <view class="phone-cell">
      <text>*</text>
      <input type="number" maxlength="11" placeholder="点击输入手机号" class="input" value="{{phoneNumber}}"
        focus="{{phoneNumberFocus}}" bindinput="phoneInput" />
    </view>
    <view class="phone-cell">
      <text>*</text>
      <view class="input-wrap">
        <input type="number" maxlength="6" placeholder="请输入验证码" placeholder-class="input-placeholder" class="input"
          value="{{verifyCode}}" bindinput="verifyInput" />
        <view class="verify-button" hover-class="verify-btn-hover" hover-stay-time="100"
          style="{{inputCodeButtonStyle}}" catchtap="tapGetVerifyCode">{{inputCodeButtonTitle || '获取验证码'}}</view>
      </view>
    </view>
  </block>

wxss

.section-title {
  margin: 0 30rpx;
  font-size: 26rpx;
  font-weight: 400;
  color: #999999;
  line-height: 28rpx;
}

.phone-cell {
  position: relative;
  display: flex;
  flex-direction: row;
  margin: 0 30rpx;
  font-size: 30rpx;
  font-weight: 400;
  color: #FF001F;
  line-height: 100rpx;
  border-top: 2rpx solid #e2e2e2;
}

.input {
  margin: auto 0 auto 8rpx;
  flex-grow: 1;
  flex-shrink: 0;
  color: #333333;
}

.input-wrap {
  position: relative;
  display: flex;
  flex-direction: row;
  flex-grow: 1;
}

.verify-button {
  flex-shrink: 0;
  height: 100rpx;
  color: #FE6400;
}

.verify-btn-hover {
  opacity: 0.75;
}

js

    tapGetVerifyCode() {
      const phoneNumber = this.data.phoneNumber;
      if (!util.checkPhoneNumber(phoneNumber)) {
        toast.showTextToast('请输入正确的手机号');
        return;
      }

      if (this.data.countingdown) {
        return;
      }

      this.initCountdownManager(false);
      toast.showTextToast('验证码已发送', null, 1.2, false);
    },

    initCountdownManager(isCheck) {
      if (this.data.countingdown) {
        return;
      }
      this.data.countingdown = true;
      countdownManager.initCountdown({
        isCheck: isCheck,
        name: 'order.popup.bindPhone.verifyCode',
        timeTotal: 60000,
        timeInterval: 1000,
        checkCallback: () => {
          this.data.countingdown = false;
        },
        timeChangedCallback: countdown => {
          this.setData({
            inputCodeButtonTitle: `重新发送(${parseInt(countdown / 1000)}s)`,
            inputCodeButtonStyle: 'color: #CCCCCC;'
          });
        },
        endCallback: () => {
          this.setData({
            inputCodeButtonTitle: '重新发送',
            inputCodeButtonStyle: 'color: #FF8134;'
          });
          this.data.countingdown = false;
        }
      });
    }

util.checkPhoneNumber

function checkPhoneNumber(phoneNumber) {
  return (phoneNumber && /^1[3-9]\d{9}$/.test(phoneNumber));
}

countdownManager.js

/**
 * 倒计时集合
 */
const countdownMap = {};

/**
 * 初始化倒计时
 * @param {string} name 倒计时类型
 * @param {*} timeTotal 总时间(毫秒)
 * @param {*} timeInterval 时间间隔(毫秒)
 * @param {*} checkCallback 检查回调函数
 * @param {*} timeChangedCallback 时间变化回调函数
 * @param {*} endCallback 结束回调函数
 */
function initCountdown({
  isCheck: isCheck = false,
  name: name,
  timeTotal: timeTotal,
  timeInterval: timeInterval,
  checkCallback: checkCallback,
  timeChangedCallback: timeChangedCallback,
  endCallback: endCallback
}) {
  if (typeof name !== 'string' || !name) {
    return;
  }
  const countdownInterval = countdownMap[name];
  if (countdownInterval) {
    clearInterval(countdownMap[name].interval);
  } else if (isCheck) {
    if (typeof checkCallback === 'function') {
      checkCallback();
    }
    return;
  } else {
    countdownMap[name] = {
      timeTotal: timeTotal,
      timeInterval: timeInterval
    };
  }
  if (typeof timeChangedCallback === 'function') {
    timeChangedCallback(countdownMap[name].timeTotal);
  }
  countdownMap[name].interval = setInterval(() => {
    if (countdownMap[name].timeTotal <= 0) {
      clearInterval(countdownMap[name].interval);
      delete countdownMap[name];
      if (typeof endCallback === 'function') {
        endCallback();
      }
      return;
    }
    countdownMap[name].timeTotal -= countdownMap[name].timeInterval;
    if (typeof timeChangedCallback === 'function') {
      timeChangedCallback(countdownMap[name].timeTotal);
    }
  }, countdownMap[name].timeInterval);
}

module.exports = {
  /**
   * 初始化倒计时
   * @param {string} name 倒计时类型
   * @param {*} timeTotal 总时间(毫秒)
   * @param {*} timeInterval 时间间隔(毫秒)
   * @param {*} timeChangedCallback 时间变化回调函数
   * @param {*} endCallback 结束回调函数
   */
  initCountdown: initCountdown
}

记录代码的点点滴滴,如果觉得有用,可以拿去直接使用。记得点赞支持!