如上图,想实现输入注册手机号,及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
}
记录代码的点点滴滴,如果觉得有用,可以拿去直接使用。记得点赞支持!