## 前言
微信小程序中,需要为用户输入提供安全密码,用于后续的操作。例如支付密码的初始设置、修改、手机号的更换、支付金额等操作。绝大部分的设计都会如图所示:
这里我就来简单的说说如何实现这个《微信小程序:自定义验证码或者密码输入框组件》。
由于一个项目中会多次使用,所以这里决定把它做成一个组件的形式。
## code(****代码****)
wxml:(代码中注释的部分是另一种写法,如果开启,请把 input 模式注释掉,样式什么的无需修改)
<view class="indep-password-box">
<view class="indep-password-box__wrapper">
<block wx:for="{{inputLength}}" wx:key="*this">
<!-- input模式 -->
<input class="indep-password-box__item"
type="number"
catchtap="_focusInput"
password="{{!showValue}}"
disabled
value="{{currentValue.length >= index + 1 ? currentValue[index] : ''}}"
style="width: {{inputWidth}}; height: {{inputHeight}};"
></input>
<!-- 自定义模式:隐藏密码时,小圆点(自定义)\显示密码时,显示对应的值 -->
<!-- <view class="indep-password-box__item"
catchtap="_focusInput"
style="width: {{inputWidth}}; height: {{inputHeight}}"
>
<view wx:if="{{!showValue && currentValue.length >= index + 1}}" class="indep-password-box__item-hidden"></view>
<view wx:if="{{showValue}}"
class="indep-password-box__item-show"
>{{currentValue.length >= index + 1 ? currentValue[index] : ''}}</view>
</view> -->
</block>
<input class="indep-password-box__input-hidden"
type="number"
password="{{true}}"
value="{{currentValue}}"
maxlength="{{inputLength}}"
focus="{{inputFocus}}"
bindinput="_setCurrentValue"
bindblur="_onInputFocus"
></input>
</view>
</view>
json:
{
"component": true,
"usingComponents": {}
}
js:
Component({
properties: {
// 输入框的数量
inputLength: {
type: Number,
value: 6
},
// 单个输入框的宽度
inputWidth: {
type: String,
value: '100rpx'
},
inputHeight: {
type: String,
value: '100rpx'
},
// 是否显示输入的值,默认隐藏
showValue: {
type: Boolean,
value: false
}
},
data: {
// input是否获取焦点
inputFocus: false,
// 初始input值为空
currentValue: ''
},
methods: {
// 设置当前的值
_setCurrentValue (e) {
// 在此处判断满6(inputLength)位,把值返回给上级父组件或页面
let currentValue = e.detail.value
// 改变时,派发一个事件,如果父组件或页面中需要实时获取改变后的值,可以监听这个事件。
this.triggerEvent('change', e.detail.value)
this.setData({ currentValue })
if (currentValue.length >= this.data.inputLength) {
this._complete(e.detail.value)
return
}
},
// 点击伪装的input时,让隐藏的input获得焦点
_focusInput (event) {
console.log('点击伪装的input时,让隐藏的input获得焦点', event)
this.setData({ inputFocus: true })
},
// 派发完成事件
_complete (value) {
console.log('派发完成事件', value)
this.triggerEvent('complete', value)
this.setData({ inputFocus: false })
},
// 处理文本框失焦
_onInputFocus (event) {
console.log('处理文本框失焦', event)
this.setData({ inputFocus: false })
},
// 提供给外部调用的方法,显示/隐藏密码。接收一个参数,可以显性修改展示的状态。
toggleValue (state) {
this.setData({ showValue: state != undefined ? state : !this.data.showValue })
},
// 清除input当前的值
clearCurrentValue () {
this.setData({ currentValue: '' })
}
}
})
wxss:
.indep-password-box {
display: flex;
justify-content: center;
align-items: center;
}
.indep-password-box__wrapper {
display: flex;
flex-direction: row;
}
/* 子项 */
.indep-password-box__wrapper .indep-password-box__item {
/* 自定义模式 */
position: relative;
display: flex;
justify-content: center;
align-items: center;
/* input模式 */
border: 1px solid #999;
box-sizing: border-box;
font-size: 12px;
text-align: center;
}
/* 边框重叠 */
.indep-password-box__wrapper .indep-password-box__item + .indep-password-box__item {
margin-left: -1rpx;
}
/* 小圆点 */
.indep-password-box .indep-password-box__wrapper .indep-password-box__item-hidden {
width: 14rpx;
height: 14rpx;
border-radius: 50%;
background: #999;
}
/* 对应值 */
.indep-password-box .indep-password-box__wrapper .indep-password-box__item-show {
color: #087b46;
}
/* 隐藏的输入框 */
.indep-password-box__wrapper .indep-password-box__input-hidden {
width: 0;
height: 0;
}
app.json:不要忘记在app.json中注册组件
,(本人是在根目录下创建的/components/
目录)
// ...
"usingComponents": {
// ...
"indep-password-box": "/components/password-box/password-box",
// ...
}
## used(****使用****)
上面是组件的定义,接下来看看如何在页面中使用它。
<indep-password-box id="passwordBox"
inputLength="{{6}}"
inputWidth="100rpx"
inputHeight="100rpx"
showValue="{{false}}"
bind:complete="setupPasswordComplete"
></indep-password-box>
onShow: function () {
this.passwordBox = this.selectComponent('#passwordBox') // 获取密码框组件,用来操作组件内部的方法
},
methods: {
// 设置密码
setupPasswordComplete (event) {
// console.log('setupPasswordComplete', event.detail)
this.setData({ 'password': event.detail })
},
// 清除密码
clearPassword() {
this.passwordBox.clearCurrentValue() // 调用组件内部的清除方法,清空输入的值
},
}
## 设计思路
设置宽高为0的方式隐藏文本框,并把隐藏的文本框作为输入的来源,通过选中单个框的点击事件,为隐藏的文本框获得焦点,再以此文本框的输入值,作为循环进行展示。
提示:后面还有精彩敬请期待,请大家关注我的专题:web前端。如有意见可以进行评论,每一条评论我都会认真对待。