uniapp 使用uview实现带-号的数字键盘

uniapp yekong

uniapp外包项目开发中,要求键盘可以负号小数点和数字,部分手机的数字键盘是没有负号的,所以使用了uview的键盘,做了一些调整后就实现了我们想要的效果。
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);
},
喜欢