微信小程序自定义键盘
效果图

功能
- 如果输入.直接补0.
- 如果是09 直接是9
- 如果是000那就有一个0
- 不能大于6位
- 小数点不能大于两位仅能出现一次
- 还有不输入是禁止支付的
- 不能小于0.01
- 失去焦点隐藏面板
- 光标问题有点小bug 望大佬指点
完整代码
wxml
<view class="page_box" catchtap="hindKeyboard">
<view class="input_view" catchtap="hindKeyboard">
<text class="title">收款金额:</text>
<view class="input_box" catchtap="showKeyboard">
<text class="input_label">¥</text>
<view class="content" wx:if="{{content.length}}">
<view wx:for="{{content}}" wx:key="index" data-str-index="{{index + 1}}" catchtap="getStrPosition">
<view class="number-block">
{{item}}
<!-- 光标 -->
<view class="cursor cursor-insert" wx:if="{{cursorIndex === index + 1}}"></view>
</view>
</view>
</view>
<view class="cursor" wx:if="{{!cursorIndex}}"></view>
<text class="default-content" wx:if="{{!content.length}}">{{defaultContent}}</text>
</view>
</view>
<!-- 键盘 -->
<view class="keyboard {{keyShow&&'hind_box'}}">
<view class="key-box">
<view class="number-box clearfix">
<view wx:for="{{KeyboardKeys}}" wx:key="*this" data-keys="{{item}}" class="key {{ index === 9 ? 'key-zero' : ''}}" hover-class="number-box-hover" catchtap="keyTap">
{{item}}
</view>
</view>
<view class="btn-box">
<!-- TODO: 需要替换成删除icon -->
<view class="key" hover-class="number-box-hover" data-keys="<" catchtap="keyTap">
X
</view>
<view class="key pay_btn {{payMoney ? '' : 'pay-btn-display'}}" hover-class="pay-btn-hover" catchtap="handlePay">
付款
</view>
</view>
</view>
</view>
</view>
wxss
page {
background: #f3f7f7;
height: 100%;
}
.page_box {
width: 100%;
height: 100%;
background: #f3f7f7;
overflow: hidden;
}
.input_view {
width: 700rpx;
height: 500rpx;
background: #fff;
margin: 25rpx auto;
border-radius: 10rpx;
padding: 40rpx;
box-sizing: border-box;
}
.title {
display: block;
line-height: 90rpx;
font-size: 30rpx;
color: #aaa;
}
.input_box {
display: flex;
align-items: center;
padding: 20rpx 0;
height: 90rpx;
border-bottom: 1px solid #efefef;
}
.input_label {
font-size: 35rpx;
font-weight: bold;
margin-right: 5rpx;
}
.content {
display: flex;
font-size: 80rpx;
line-height: 90rpx;
font-weight: 700;
}
.number-block {
position: relative;
}
/* 光标 */
.cursor-insert {
position: absolute;
top: 0rpx;
right: -1rpx;
}
.cursor {
width: 2rpx;
height: 90rpx;
background: #666;
border-radius: 6rpx;
animation: twinkling 0.9s infinite;
}
@-webkit-keyframes twinkling {
0% {
background: #fff;
}
100% {
background: #666;
}
}
.default-content {
color: #999;
font-size: 38rpx;
font-weight: 600;
}
/* 键盘 */
.keyboard {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
height: 0;
background: #f7f7f7;
transition: height 0.3s;
}
.hind_box {
height: 456rpx;
}
.key-box {
display: flex;
padding-left: 16rpx;
padding-bottom: 16rpx;
padding-bottom: calc(16rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
}
.number-box {
flex: 3;
}
.number-box .key {
float: left;
margin: 16rpx 16rpx 0 0;
width: calc(100% / 3 - 16rpx);
height: 90rpx;
border-radius: 10rpx;
line-height: 90rpx;
text-align: center;
font-size: 40rpx;
font-weight: bold;
background-color: #fff;
}
.number-box .key.key-zero {
width: calc((100% / 3) * 2 - 16rpx);
}
.keyboard .number-box-hover {
/* 临时定义颜色 */
background-color: #e1e1e1 !important;
}
.btn-box {
flex: 1;
}
.btn-box .key {
margin: 16rpx 16rpx 0 0;
height: 90rpx;
border-radius: 10rpx;
line-height: 90rpx;
text-align: center;
font-size: 40rpx;
font-weight: bold;
background-color: #fff;
}
.btn-box .pay_btn {
height: 298rpx;
line-height: 298rpx;
font-weight: normal;
background-color: #1AAD19;
color: #fff;
font-size: 32rpx;
}
.btn-box .pay_btn.pay-btn-display {
background-color: #9ED99D !important;
}
.btn-box .pay_btn.pay-btn-hover {
background-color: #179B16;
}
js
// pages/inputs/inputs.js
Page({
data: {
content: [], // 输入的金额
payMoney: '', // 支付金额
defaultContent: '请输入', // 默认内容
KeyboardKeys: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.'],
keyShow: true, // 是否展示键盘
cursorIndex: '', // 插入光标位置
},
//点击界面键盘消失
hindKeyboard() {
this.setData({ keyShow: false });
},
//点击输入框,键盘显示
showKeyboard() {
this.setData({ keyShow: true });
},
// 获取插入光标位置
getStrPosition(e) {
let { strIndex } = e.currentTarget.dataset
this.setData({ cursorIndex: strIndex })
},
keyTap(e) {
let { keys } = e.currentTarget.dataset,
content = this.data.content.join(''), // 转为字符串
strLen = content.length,
{ cursorIndex } = this.data
switch (keys) {
case '.':
if (content.indexOf('.') === -1) { // 已有一个点的情况下
content.length < 1 ? content = '0.' : content += '.'
}
break
case '<':
if (cursorIndex > 0 && cursorIndex !== strLen) {
// 从插入光标开始删除元素
this.data.content.splice(cursorIndex - 1, 1)
content = this.data.content.join('')
} else {
content = content.substr(0, content.length - 1)
}
if (!strLen || cursorIndex === strLen) { // 插入光标位置重置
this.setData({ cursorIndex: '' })
}
// 删除点 组件中可以用Observer监听删除点和删除0的情况
if (content[0] === '0' && content[1] !== '.') {
content = content.substr(1, content.length - 1)
}
if (content[0] === '.') {
content = '0' + content
}
break
default:
let spotIndex = content.indexOf('.') //小数点的位置
if (content[0] === '0' && content[1] !== '.') {
content = content.substr(1, content.length - 1)
}
if ((spotIndex === -1 || strLen - spotIndex !== 3)) { //小数点后只保留两位
content += keys
}
break
}
if (content <= 100000) {
this.setData(
{
content: content.split(''),// 转为数组
payMoney: content // 支付金额
}
)
} else {
wx.showToast({
title: '支付金额不能大于100000',
icon: 'none',
duration: 1500,
})
}
},
handlePay() {
const { payMoney } = this.data
if (payMoney === '') return
if (payMoney < '0.01') {
wx.showToast({
title: '支付金额不能小于0.01',
icon: 'none',
duration: 1500,
})
return
}
console.log(Number(payMoney), '付款')
}
})