uniapp外包项目开发中,要求键盘可以负号小数点和数字,部分手机的数字键盘是没有负号的,所以使用了uview的键盘,做了一些调整后就实现了我们想要的效果。
u-keyboard 增加类型 negativeNumber
<template>
<u-popup :overlay="overlay" :closeOnClickOverlay="closeOnClickOverlay" mode="bottom" :popup="false" :show="show"
:safeAreaInsetBottom="safeAreaInsetBottom" @close="popupClose" :zIndex="zIndex" :customStyle="{
backgroundColor: 'rgb(214, 218, 220)'
}">
<view class="u-keyboard">
<slot />
<view class="u-keyboard__tooltip" v-if="tooltip">
<view hover-class="u-hover-class" :hover-stay-time="100">
<text class="u-keyboard__tooltip__item u-keyboard__tooltip__cancel" v-if="showCancel"
@tap="onCancel">{{showCancel && cancelText}}</text>
</view>
<view>
<text v-if="showTips" class="u-keyboard__tooltip__item u-keyboard__tooltip__tips">{{tips}}</text>
</view>
<view hover-class="u-hover-class" :hover-stay-time="100">
<text v-if="showConfirm" @tap="onConfirm"
class="u-keyboard__tooltip__item u-keyboard__tooltip__submit"
hover-class="u-hover-class">{{showConfirm && confirmText}}</text>
</view>
</view>
<template v-if="mode == 'number' || mode == 'card' || mode == 'negativeNumber'">
<u-number-keyboard :random="random" @backspace="backspace" @change="change" :mode="mode"
:dotDisabled="dotDisabled"></u-number-keyboard>
</template>
<template v-else>
<u-car-keyboard :random="random" :autoChange="autoChange" @backspace="backspace" @change="change">
</u-car-keyboard>
</template>
</view>
</u-popup>
</template>
<script>
import props from './props.js';
/**
* keyboard 键盘
* @description 此为uViw自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3中模式,都有可以打乱按键顺序的选项。
* @tutorial https://www.uviewui.com/components/keyboard.html
* @property {String} mode 键盘类型,见官网基本使用的说明 (默认 'number' )
* @property {Boolean} dotDisabled 是否显示"."按键,只在mode=number时有效 (默认 false )
* @property {Boolean} tooltip 是否显示键盘顶部工具条 (默认 true )
* @property {Boolean} showTips 是否显示工具条中间的提示 (默认 true )
* @property {String} tips 工具条中间的提示文字,见上方基本使用的说明,如不需要,请传""空字符
* @property {Boolean} showCancel 是否显示工具条左边的"取消"按钮 (默认 true )
* @property {Boolean} showConfirm 是否显示工具条右边的"完成"按钮( 默认 true )
* @property {Boolean} random 是否打乱键盘按键的顺序 (默认 false )
* @property {Boolean} safeAreaInsetBottom 是否开启底部安全区适配 (默认 true )
* @property {Boolean} closeOnClickOverlay 是否允许点击遮罩收起键盘 (默认 true )
* @property {Boolean} show 控制键盘的弹出与收起(默认 false )
* @property {Boolean} overlay 是否显示遮罩 (默认 true )
* @property {String | Number} zIndex 弹出键盘的z-index值 (默认 1075 )
* @property {String} cancelText 取消按钮的文字 (默认 '取消' )
* @property {String} confirmText 确认按钮的文字 (默认 '确认' )
* @property {Object} customStyle 自定义样式,对象形式
* @event {Function} change 按键被点击(不包含退格键被点击)
* @event {Function} cancel 键盘顶部工具条左边的"取消"按钮被点击
* @event {Function} confirm 键盘顶部工具条右边的"完成"按钮被点击
* @event {Function} backspace 键盘退格键被点击
* @example <u-keyboard mode="number" v-model="show"></u-keyboard>
*/
export default {
name: "u-keyboard",
data() {
return {
}
},
mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
methods: {
change(e) {
this.$emit('change', e);
},
// 键盘关闭
popupClose() {
this.$emit('close');
},
// 输入完成
onConfirm() {
this.$emit('confirm');
},
// 取消输入
onCancel() {
this.$emit('cancel');
},
// 退格键
backspace() {
this.$emit('backspace');
}
}
}
</script>
<style lang="scss" scoped>
@import "../../libs/css/components.scss";
.u-keyboard {
&__tooltip {
@include flex;
justify-content: space-between;
background-color: #FFFFFF;
padding: 14px 12px;
&__item {
color: #333333;
flex: 1;
text-align: center;
font-size: 15px;
}
&__submit {
text-align: right;
color: $u-primary;
}
&__cancel {
text-align: left;
color: #888888;
}
&__tips {
color: $u-tips-color;
}
}
}
</style>
u-number-keyboard 增加类型
<template>
<view class="u-keyboard" @touchmove.stop.prevent="noop">
<view class="u-keyboard__button-wrapper" v-for="(item, index) in numList" :key="index">
<view class="u-keyboard__button-wrapper__button" :style="[itemStyle(index)]" @tap="keyboardClick(item)"
hover-class="u-hover-class" :hover-stay-time="200">
<text class="u-keyboard__button-wrapper__button__text">{{ item }}</text>
</view>
</view>
<view class="u-keyboard__button-wrapper">
<view class="u-keyboard__button-wrapper__button u-keyboard__button-wrapper__button--gray"
hover-class="u-hover-class" :hover-stay-time="200" @touchstart.stop="backspaceClick"
@touchend="clearTimer">
<u-icon name="backspace" color="#303133" size="28"></u-icon>
</view>
</view>
</view>
</template>
<script>
import props from './props.js';
/**
* keyboard 键盘组件
* @description
* @tutorial
* @property {String} mode 键盘的类型,number-数字键盘,card-身份证键盘
* @property {Boolean} dotDisabled 是否显示键盘的"."符号
* @property {Boolean} random 是否打乱键盘按键的顺序
* @event {Function} change 点击键盘触发
* @event {Function} backspace 点击退格键触发
* @example
*/
export default {
mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
data() {
return {
backspace: 'backspace', // 退格键内容
dot: '.', // 点
minus: '-', // 点
timer: null, // 长按多次删除的事件监听
cardX: 'X' // 身份证的X符号
};
},
computed: {
// 键盘需要显示的内容
numList() {
let tmp = [];
if (this.dotDisabled && this.mode == 'number') {
if (!this.random) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
} else {
return uni.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
}
} else if (!this.dotDisabled && this.mode == 'number') {
if (!this.random) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, this.dot, 0];
} else {
return uni.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, this.dot, 0]);
}
} else if (this.mode == 'card') {
if (!this.random) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, this.cardX, 0];
} else {
return uni.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, this.cardX, 0]);
}
} else if (this.mode == 'negativeNumber') {
if (!this.random) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, this.minus, this.dot, 0];
} else {
return uni.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, this.minus, this.dot, 0]);
}
}
},
// 按键的样式,在非乱序&&数字键盘&&不显示点按钮时,index为9时,按键占位两个空间
itemStyle() {
return index => {
let style = {};
if (this.mode == 'number' && this.dotDisabled && index == 9) style.width = '464rpx';
return style;
};
},
// 是否让按键显示灰色,只在非乱序&&数字键盘&&且允许点按键的时候
btnBgGray() {
return index => {
if (!this.random && index == 9 && (this.mode != 'number' || (this.mode == 'number' && !this
.dotDisabled))) return true;
else return false;
};
},
},
created() {
},
methods: {
// 点击退格键
backspaceClick() {
this.$emit('backspace');
clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
this.timer = null;
this.timer = setInterval(() => {
this.$emit('backspace');
}, 250);
},
clearTimer() {
clearInterval(this.timer);
this.timer = null;
},
// 获取键盘显示的内容
keyboardClick(val) {
// 允许键盘显示点模式和触发非点按键时,将内容转为数字类型
if (!this.dotDisabled && val != this.dot && val != this.cardX && val != this.minus) val = Number(val);
this.$emit('change', val);
}
}
};
</script>
<style lang="scss" scoped>
@import "../../libs/css/components.scss";
$u-number-keyboard-background-color:rgb(224, 228, 230) !default;
$u-number-keyboard-padding:8px 10rpx 8px 10rpx !default;
$u-number-keyboard-button-width:222rpx !default;
$u-number-keyboard-button-margin:4px 6rpx !default;
$u-number-keyboard-button-border-top-left-radius:4px !default;
$u-number-keyboard-button-border-top-right-radius:4px !default;
$u-number-keyboard-button-border-bottom-left-radius:4px !default;
$u-number-keyboard-button-border-bottom-right-radius:4px !default;
$u-number-keyboard-button-height: 90rpx !default;
$u-number-keyboard-button-background-color:#FFFFFF !default;
$u-number-keyboard-button-box-shadow:0 2px 0px #BBBCBE !default;
$u-number-keyboard-text-font-size:20px !default;
$u-number-keyboard-text-font-weight:500 !default;
$u-number-keyboard-text-color:$u-main-color !default;
$u-number-keyboard-gray-background-color:rgb(200, 202, 210) !default;
$u-number-keyboard-u-hover-class-background-color: #BBBCC6 !default;
.u-keyboard {
@include flex;
flex-direction: row;
justify-content: space-around;
background-color: $u-number-keyboard-background-color;
flex-wrap: wrap;
padding: $u-number-keyboard-padding;
&__button-wrapper {
box-shadow: $u-number-keyboard-button-box-shadow;
margin: $u-number-keyboard-button-margin;
border-top-left-radius: $u-number-keyboard-button-border-top-left-radius;
border-top-right-radius: $u-number-keyboard-button-border-top-right-radius;
border-bottom-left-radius: $u-number-keyboard-button-border-bottom-left-radius;
border-bottom-right-radius: $u-number-keyboard-button-border-bottom-right-radius;
&__button {
width: $u-number-keyboard-button-width;
height: $u-number-keyboard-button-height;
background-color: $u-number-keyboard-button-background-color;
@include flex;
justify-content: center;
align-items: center;
border-top-left-radius: $u-number-keyboard-button-border-top-left-radius;
border-top-right-radius: $u-number-keyboard-button-border-top-right-radius;
border-bottom-left-radius: $u-number-keyboard-button-border-bottom-left-radius;
border-bottom-right-radius: $u-number-keyboard-button-border-bottom-right-radius;
&__text {
font-size: $u-number-keyboard-text-font-size;
font-weight: $u-number-keyboard-text-font-weight;
color: $u-number-keyboard-text-color;
}
&--gray {
background-color: $u-number-keyboard-gray-background-color;
}
}
}
}
.u-hover-class {
background-color: $u-number-keyboard-u-hover-class-background-color;
}
</style>
使用
<u-keyboard @change="valChange" @confirm="confirm" @cancel="cancel" @backspace="backspace" tips="存入金额"
ref="uKeyboard" mode="number2" :show="showKeyboard">
<span class="NumberInput">{{data.PaymentAmount}}</span>
</u-keyboard>
// 按键被点击(点击退格键不会触发此事件)
valChange(val) {
if (val == '.') {
if (!this.data.PaymentAmount.includes('.')) {
if (this.data.PaymentAmount.length > 0) {
var regstr = new RegExp("^\d+$");
var str = this.data.PaymentAmount.charAt(this.data.PaymentAmount.length - 1)
if (regstr.test(str)) {
console.log(regstr.test(str))
this.data.PaymentAmount = this.data.PaymentAmount + val;
} else {
this.data.PaymentAmount = this.data.PaymentAmount + '0' + val;
}
} else {
this.data.PaymentAmount = '0' + val;
}
}
} else if (val == '-') {
if (!this.data.PaymentAmount.includes('-')) {
this.data.PaymentAmount = '-' + this.data.PaymentAmount;
}
} else {
this.data.PaymentAmount = this.data.PaymentAmount + val;
}
},
confirm() {
this.showKeyboard = false
},
cancel() {
this.showKeyboard = false
},
// 退格键被点击
backspace() {
// 删除value的最后一个字符
if (this.data.PaymentAmount.length) this.data.PaymentAmount = this.data.PaymentAmount.substr(0, this.data
.PaymentAmount.length - 1);
console.log(this.data.PaymentAmount);
},