需求
實現(xiàn)一個能夠輸入6位密碼框組件(如微信支付密碼框類似)
思路一(不可行方案)
使用一個Input 配合 letter-spacing 屬性使用。后實驗下來盆耽,input 并不使用css中的 letter-spacing 屬性冰肴。
思路二 (可行方案)
在頁面中俗壹,隱藏一個input,然后控制 input 組件的 focus 屬性從而實現(xiàn)6位密碼框輸入脐嫂。
需要注意的是匠抗,在我寫這個組件并驗證時故源,(iphone xs max ios13.3) 微信版本為7.0.8,實測組件可以正常工作汞贸。當我微信升級為7.0.9時绳军,input 手動設置 focus 并沒有生效,同時矢腻,該 input 沒有辦法再次聚焦并彈出輸入法门驾。(很奇怪的是,我同事的手機也是iphone xs max ios13.3 微信 7.0.9 沒有這個問題
組件布局拆分
組件wxml
<view class="pay-password-container">
<text class="pay-password-title">安全驗證</text>
<text class="pay-password-tips">您使用了虛擬資產(chǎn)多柑,為保障安全奶是,請輸入支付密碼!</text>
<view style="position:relative">
<view class="pay-password-layout">
<view wx:for="{{passwordlayout}}" class="pay-password-item">
<view wx:if="{{index < passwordCode.length}}" class="dot" />
</view>
</view>
<!-- 這里采用了一個投機取巧的辦法竣灌,使用兩個Input 防止在某些機型上,input設置focus會導致input整個失效-->
<input value="{{passwordCode}}" password maxlength="6" type="number" class='input-container-2' bindinput="passwordInput" />
</view>
<input value="{{passwordCode}}" focus="{{focus}}" maxlength="6" type="number" class='input-container-2' bindinput="passwordInput" bindfocus="getFocus" bindblur="blur" />
<view class='forget-password' catchtap="clickForgetPassword">忘記密碼?</view>
<view class="empty-layout" />
<view class="controll-layout">
<view class="cancel-button" catchtap="dismiss">
<text>取消</text>
</view>
<view class="divider" />
<view class="sure-button" catchtap="sure">
<text>確定</text>
</view>
</view>
</view>
組件wxss
.pay-password-container {
width: 650rpx;
height: 525rpx;
border-radius: 16rpx;
background: #fff;
display: flex;
display: -webkit-flex;
flex-direction: column;
align-items: center;
}
.pay-password-title {
font-size: 40rpx;
font-weight: bold;
color: #030303;
margin-top: 59rpx;
flex-shrink: 0;
}
.pay-password-tips {
font-size: 24rpx;
color: #333;
opacity: 0.5;
margin-top: 31rpx;
flex-shrink: 0;
}
.pay-password-layout {
display: flex;
display: -webkit-flex;
flex-direction: row;
margin-top: 40rpx;
flex-shrink: 0;
z-index: 105rpx;
}
.pay-password-item:first-child {
height: 90rpx;
width: 90rpx;
border-radius: 8rpx 0rpx 0rpx 8rpx;
border-top: 1px solid #bbb;
border-left: 1px solid #bbb;
border-bottom: 1px solid #bbb;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
display: flex;
display: -webkit-flex;
justify-content: center;
align-items: center;
}
.pay-password-item {
height: 90rpx;
width: 90rpx;
border-top: 1px solid #bbb;
border-left: 1px solid #bbb;
border-bottom: 1px solid #bbb;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
display: flex;
display: -webkit-flex;
justify-content: center;
align-items: center;
}
.pay-password-item:last-child {
height: 90rpx;
width: 90rpx;
border-radius: 0rpx 8rpx 8rpx 0rpx;
border-top: 1px solid #bbb;
border-left: 1px solid #bbb;
border-bottom: 1px solid #bbb;
border-right: 1px solid #bbb;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
display: flex;
display: -webkit-flex;
justify-content: center;
align-items: center;
}
.pay-password-item .dot {
height: 20rpx;
width: 20rpx;
background: #030303;
border-radius: 50%;
}
.input-container-2 {
position: absolute;
top: 40rpx;
height: 100rpx;
width: 1500rpx;
left: -500rpx;
}
.empty-layout {
flex-grow: 1;
}
.controll-layout {
flex-shrink: 0;
border-top: 1px solid #e9e9e9;
width: 100%;
height: 100rpx;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
display: flex;
display: -webkit-flex;
}
.controll-layout .cancel-button {
flex-grow: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
align-items: center;
}
.cancel-button text {
color: #333;
opacity: 0.5;
font-size: 34rpx;
}
.controll-layout .divider {
background: #e9e9e9;
height: 100%;
width: 1px;
flex-shrink: 0;
}
.controll-layout .sure-button {
flex-grow: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
align-items: center;
}
.sure-button text {
font-size: 34rpx;
color: #f8aa00;
font-weight: bold;
}
.forget-password {
font-size: 24rpx;
color: #333;
opacity: 0.5;
margin-top: 30rpx;
align-self: flex-end;
margin-right: 55rpx;
}
組件js
input1 帶 focus 屬性及汉,手動設置 focus 讓其彈出。
input2 不帶 focus 屬性坷随,需要用戶手動點擊輸入框(6格)后,輸入甸箱。
這樣就避免了對 輸入框(6格)監(jiān)聽tap事件育叁,并設置focus 來讓 input 聚焦,讓輸入法彈起豪嗽。就解決了部分手機上手動設置 focus 會導致 input 組件沒有響應的問題谴蔑。
Component({
data: {
passwordlayout: [1, 1, 1, 1, 1, 1],
passwordCode: "",
focus: false
},
methods: {
showModal: function () {
this.setData({
focus: true
})
},
closeModal: function () {
this._clearData();
},
passwordInput: function (e) {
this.setData({
passwordCode: e.detail.value
})
},
focusInput: function () {
this.setData({
focus: true
})
},
getFocus: function () {
this.setData({
focus: true
})
},
blur: function () {
this.setData({
focus: false
})
},
dismiss: function (e) {
this.closeModal();
},
sure: function (e) {
if (this.data.passwordCode.length < 6) {
UIManager.showToast('請輸入支付密碼');
return;
}
//todo 支付密碼驗證
},
clickForgetPassword: function (e) {
//todo 忘記密碼
},
}
})