视觉效果
其实是通过偏移了 input 输入框(input 设置最大长度),然后根据输入框的 value 值的输入设置六个方框的显示效果,最终所需要的只是 input 的 value 值,并判断当它到达最大长度时的输入校验。
思路
创建类名 container 作为最外层
创建类名 inputWrap 作为内容层
其包含 关闭(close),提示(tip),还有 6 个小框(itemWrap -> item)
小框(item)通过 wx:for 实现,然后判断 input 的 value 值长度是否大于i,是则显示小框中的圆(text样式)
设置 input 类型 password,获取事件,最大长度,由于要设置input偏移,所以需要设置聚焦 focus
pages/index/index.wxml
// 点击事件显示密码输入
<button bindtap="showPwdWrap">点击弹出</button>
<view class="container" wx:if="{{isShowPwdWrap}}">
<view class="inputWrap" catchtap="getFocus">
<view class="close" bindtap="hiddenPwdWrap">x</view>
<view class="tip">请输入密码</view>
<view class="itemWrap">
<view class="item" wx:for="{{6}}" wx:key="item" wx:for-index="i">
<text wx:if="{{password.length > i}}"></text>
</view>
</view>
<input class="input_contr" type="number" value="{{password}}" focus="{{inputFocus}}" password bindinput="inputPwd" maxlength="6" />
</view>
</view>
pages/index/index.js
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
isShowPwdWrap: false,
password: '',
inputFocus: true
},
showPwdWrap: function () {
this.setData({
inputFocus: true,
isShowPwdWrap: true
})
},
// 聚焦
getFocus: function (e) {
this.setData({
inputFocus: true
})
},
// 获取input输入的值并检验
inputPwd: function (e) {
this.setData({
password: e.detail.value
});
if(this.data.password.length >= 6) {
wx.showToast({
title: '正在检验中...',
icon: 'none',
image: '',
duration: 1000,
mask: true
});
// 检验 模拟异步
setTimeout(() => {
if(this.data.pwd === this.data.password) {
// 成功
wx.showToast({
title: '成功...',
image: '',
duration: 2000,
mask: true
});
// 隐藏
this.hiddenPwdWrap();
} else {
// 失败
this.setData({
password: ''
});
wx.showToast({
title: '请重新输入密码...',
icon: 'none',
image: '',
duration: 2000,
mask: true
});
}
}, 1000);
}
},
// 隐藏
hiddenPwdWrap: function () {
this.setData({
isShowPwdWrap: false,
inputFocus: false,
password: ''
})
}
})
pages/index/index.wxss
.container {
background-color: rgba(0, 0, 0, 0.68);
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
}
.container .inputWrap {
position: absolute;
top: 430rpx;
left: 0;
width: calc(100% - 58rpx);
margin: 30rpx;
height: 30%;
transform: translateY(-50%);
background-color: #fff;
}
.container .inputWrap .close {
display: flex;
justify-content: flex-end;
font-size: 62rpx;
font-weight: 400;
color: #666;
margin-right: 40rpx;
}
.container .inputWrap .tip {
width: 80%;
margin-left: 10%;
margin-bottom: 10%;
color: #666;
}
.container .inputWrap .itemWrap {
display: flex;
justify-content: space-between;
margin-left: 10%;
width: 80%;
color: #666;
}
.container .inputWrap .itemWrap .item {
width: 79rpx;
height: 79rpx;
border: solid 1rpx #ccc;
display: flex;
justify-content: center;
align-items: center;
}
.container .inputWrap .itemWrap .item text {
width: 30rpx;
height: 30rpx;
background-color: #3f3c3c;
border-radius: 20rpx;
}
.container .inputWrap .input_contr {
position: relative;
left: -9999rpx;
}
加入验证模态框
通过 pages/index/index.js 两个布尔变量来设置
close 是否关闭
secSuc 是否成功
视图模板设置
最外层 类名 modelWrap,通过判断 close 来显示隐藏
内容层 类名 modelMain,包含以下
文字一:检验中,其样式变化跟随 secSuc 变量来设置
加载:通过 wx:for 设置三个圆点,样式也跟随 secSuc 变量来设置
文字二:成功,其样式变化跟随 secSuc 变量来设置
components/stepModel/index.js
Component({
/**
* 组件的属性列表
*/
properties: {
close: {
type: Boolean,
value: false
},
secSuc: {
type: Boolean,
value: false
},
},
})
components/stepModel/index.wxml
<view class="modelWrap">
<view class="modelMain">
<view class="{{secSuc ? '' : 'cr_red'}}">检验中</view>
<view class="loading">
<view class="{{secSuc ? 'item2' : 'item'}}" wx:for="{{3}}" wx:key="*this"></view>
</view>
<view class="{{secSuc ? 'cr_red' : ''}}">成功</view>
</view>
</view>
components/stepModel/index.wxss
.modelWrap {
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
}
.modelWrap .modelMain {
position: absolute;
top: 430rpx;
transform: translateY(-50%);
background-color: #fff;
width: calc(100% - 58rpx);
height: 30%;
margin: 30rpx;
display: flex;
justify-content: center;
align-items: center;
}
.modelWrap .modelMain .loading {
width: 90rpx;
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 20rpx;
}
.modelWrap .modelMain .loading .item {
width: 25rpx;
height: 25rpx;
display: flex;
justify-content: space-between;
border-radius: 20rpx;
background-color: #ccc;
animation: move 1s linear infinite alternate;
}
.modelWrap .modelMain .loading .item:nth-child(2) {
animation-delay: 0.6s;
}
.modelWrap .modelMain .loading .item:last-child {
animation-delay: 1.2s;
}
.modelWrap .modelMain .item2 {
width: 25rpx;
height: 25rpx;
display: flex;
justify-content: space-between;
border-radius: 20rpx;
background-color: #ccc;
}
.modelWrap .modelMain .cr_red {
color: red;
}
@keyframes move {
0% {
background-color: #ccc;
}
100% {
background-color: #df8f17;
}
}
pages/index/index.wxml
需先声明,以下是引用
<step-model wx:if="{{close}}" secSuc="{{secSuc}}"></step-model>
pages/index/index.js
在 获取input输入的值并检验的事件中加入相应逻辑
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
tabList: ['首页', '新闻','我的'],
index: 0,
isShowPwdWrap: false,
password: '',
inputFocus: true,
// 模拟检验的密码
pwd: '123456',
close: false,
secSuc: false
},
getIndex (e) {
const {index} = e.detail;
this.setData({
index: index
})
},
showPwdWrap: function () {
this.setData({
inputFocus: true,
isShowPwdWrap: true
})
},
// 聚焦
getFocus: function (e) {
this.setData({
inputFocus: true
})
},
// 获取input输入的值并检验
inputPwd: function (e) {
this.setData({
password: e.detail.value
});
if(this.data.password.length >= 6) {
this.setData({
close: true,
secSuc: false
})
// 检验
setTimeout(() => {
if(this.data.pwd === this.data.password) {
this.setData({
secSuc: true
})
setTimeout(() => {
this.hiddenPwdWrap();
this.setData({
close: false
});
}, 1000);
} else {
this.setData({
close: false,
password: ''
});
wx.showToast({
title: '请重新输入密码...',
icon: 'none',
image: '',
duration: 2000,
mask: true
});
}
}, 1000);
}
},
// 隐藏
hiddenPwdWrap: function () {
this.setData({
isShowPwdWrap: false,
inputFocus: false,
password: ''
})
}
})