小程序 自定义键盘

父组件

<template>
	<view class="repayment">		
			<view class="detail">
				<button type="default" @click="onSure">确认还款</button>
			</view>
		<u-popup @close="close" v-model="noteShow" mode="bottom" closeable="true">
			<view class="note">
                                <validcode class="keyInput"  ref="keyInput" :codeArr="codeArr" :val="NUM" :maxlength="6" :isPwd="false" @finish="finish"></validcode>
				<keyboard ref="keyBoard" @change = "changeKey" @del = "del" :show = "showKey"></keyboard>
			</view>
		</u-popup>
	</view>

</template>

<script>	
	export default {
		data() {
			return {
				
				showKey:false,
				NUM:"",
				codeArr:[],
			}
		},
		onLoad() {},
		methods: {
			changeKey(val){
				this.NUM = val;
				this.codeArr = this.NUM.split('');
			},
			del(val){
				this.NUM = val;
				this.codeArr = this.NUM.split('');
			},
                        finish(){
				this.NUM = "";
				this.codeArr = [];
				//还款结果
				uni.navigateTo({
					url:"/pages/repayment/resultPage"
				});
				this.detailShow = false;
				this.selectShow = false;
				this.noteShow = false;
				
			},
			
			onSure(){
				//确认还款
				// this.detailShow = false;
				this.NUM = "";
				this.codeArr = [];
				this.showKey = true;
				this.$refs.keyBoard.focus();
			},
			

		}
	}
</script>

<style lang="less" scoped>
	
</style>

复制代码

键盘子组件

<template>
	<view class="keyBoardWrapper">
		<view class="keyBoard" v-if="show">
			<view class="num">
				<u-table>
					<u-tr>
						<u-td :class="[active === num ? 'active':'']" @touchstart="msDown(num)" @touchend="msUp(num)"
							v-for="(num,k) in arr[0]" :key="k">
							<view @click="change(num)" >
								<text>{{num}}</text>
								<text class="Atext">{{Array[0][k]}}</text>
							</view>
						</u-td>
					</u-tr>
					<u-tr>
						<u-td :class="[active === num ? 'active':'']" @touchstart="msDown(num)" @touchend="msUp(num)"
							v-for="(num,k) in arr[1]" :key="k">
							<view @click="change(num)" >
								<text>{{num}}</text>
								<text class="Atext">{{Array[1][k]}}</text>
							</view>
						</u-td>
					</u-tr>
					<u-tr>
						<u-td :class="[active === num ? 'active':'']" @touchstart="msDown(num)" @touchend="msUp(num)"
							v-for="(num,k) in arr[2]" :key="k">
							<view @click="change(num)" >
								<text>{{num}}</text>
								<text class="Atext">{{Array[2][k]}}</text>
							</view>
						</u-td>
					</u-tr>
					<u-tr>
						<u-td rowspan="2" class="tdNull"></u-td>
						<u-td rowspan="2" :class="[active === num ? 'active':'']" @touchstart="msDown(num)"
							@touchend="msUp(num)" v-for="(num,k) in arr[3]" :key="k">
							<text @click="change(num)">{{num}}</text>
						</u-td>
						<u-td rowspan="2" class="tdNull">
							<view class="delView" @click="del">
								<u-icon name="backspace" color="#9BA0AA" size="60"></u-icon>
								<!-- <image class="del" src="https://juejin.cn/static/img/checked.png" mode=""></image> -->
							</view>
						</u-td>
					</u-tr>
				</u-table>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			show: {
				type: Boolean,
				default: false,
			},
		},
		data() {
			return {
				active: null,
				result: [],
				NUM: '',
				list: [1, 2, 3],
				arr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0],
				Array:['','ABC','DEF','GHI','JKL','MNO','PQRS','TUV','WXYZ']
			}
		},
		watch: {
			show(val) {
				this.NUM = '';
				this.result = [];
			}
		},
		methods: {
			msDown(v) {
				this.active = v;
			},
			msUp(v) {
				this.active = "";
			},
			change(val, $event) {
				if (this.result.length === 0 && val === ".") {
					return false;
				} else {
					this.result.push(val);
					this.NUM = this.result.join("");
				}
				this.$emit("change", this.NUM);
			},
			del() {
				this.result.pop();
				this.NUM = this.result.join("");
				this.$emit("del", this.NUM);
			},
			group(array, len) {
				let index = 0;
				let newArray = [];
				while (index < array.length) {
					newArray.push(array.slice(index, (index += len)));
				}
				return newArray;
			},
			focus() {
				this.arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
				this.Array = ['','ABC','DEF','GHI','JKL','MNO','PQRS','TUV','WXYZ']
				this.arr = this.group(this.arr, 3);
				this.Array = this.group(this.Array,3);
			}
		}
	}
</script>

<style lang="less" scoped>
	.keyBoardWrapper {
		user-select: none;

		.keyBoard {
			.num {
				u-table {
					width: 100%;
					border-collapse: collapse;
					background: #FFFFFF;
					u-td {
						height: 108rpx;
						vertical-align: middle;
						font-size: 20rpx;
						text-align: center;
						text {
							display: block;
							font-size: 42rpx;
						};
						.Atext{
							font-size: 22rpx;
						}
						view{
							width: 100%;
							font-weight: 400;
						};
					}

					u-td .active {
						background: #ccc;
					}

					.delView {
						height: 108rpx;
						line-height: 130rpx;
					}

					.tdNull {
						background: #E3E6ED;
					}

					.del {
						width: 45rpx;
						height: 45rpx;
						margin: 0 auto;
					}
				}
			}
		}
	}
</style>

复制代码

输入框子组件

<template>
	<view class="code-area" :style="marginTop?'margin-bottom: 300rpx;':''">
		<view class="flex-box">
			<input
			    :value="val"
				type="text"
				:maxlength="maxlength"
				class="hide-input"
			/>
			<view class="item">
				<block v-if="isPwd && codeArr.length >= 1">
					<text class="dot">.</text>
				</block>
				<block v-else>	{{ codeArr[0] ? codeArr[0] : ''}}</block>
			</view>
			<view class="item">
				<block v-if="isPwd && codeArr.length >= 2">
					<text class="dot">.</text>
				</block>
				<block v-else>	{{ codeArr[1] ? codeArr[1] : ''}}</block>
			</view>
			<view class="item">
				<block v-if="isPwd && codeArr.length >= 3">
					<text class="dot">.</text>
				</block>
				<block v-else>	{{ codeArr[2] ? codeArr[2] : ''}}</block>
			</view>
			<view class="item">
				<block v-if="isPwd && codeArr.length >= 4">
					<text class="dot">.</text>
				</block>
				<block v-else>	{{ codeArr[3] ? codeArr[3] : ''}}</block>
			</view>
			<block v-if="maxlength === 6">				
				<view class="item">
					<block v-if="isPwd && codeArr.length >= 5">
						<text class="dot">.</text>
					</block>
					<block v-else>	{{ codeArr[4] ? codeArr[4] : ''}}</block>
				</view>
				<view class="item">
					<block v-if="isPwd && codeArr.length >= 6">
						<text class="dot">.</text>
					</block>
					<block v-else>	{{ codeArr[5] ? codeArr[5] : ''}}</block>
				</view>
			</block>
		</view>
	</view>
</template>

<script>
export default {
	props: {
		//最大长度 值为4或者6
		maxlength: {
			type: Number,
			default: 4
		},
		//是否是密码
		isPwd: {
			type: Boolean,
			default: false
		},
		val:{
			type:String,
			default:'',
		},
		codeArr:{
			type:Array,
			default:[],
		},
		marginTop:{
			type: Boolean,
			default: true
		}
	},
	data() {
		return {
			codeIndex: 1, //下标
		};
	},
	methods: {
		//取值
		getVal() {
			this.codeIndex = this.codeArr.length + 1;
			if (this.codeIndex >= Number(this.maxlength)) {
				//输入完成
				this.$emit('finish');
			}
		},
	},
};
</script>

<style lang="scss">
.code-area {
	text-align: center;
	.flex-box {
		display: flex;
		flex-wrap: wrap;
		position: relative;
		justify-content: center;
	}
	.item {
		position: relative;
		width: 100upx;
		height: 100upx;
		margin-right: 18upx;
		font-size: 30upx;
		font-weight: bold;
		color: #333333;
		line-height: 100upx;
		box-sizing: border-box;
		border: 2upx solid #cccccc;
	}
	.item:last-child {
		margin-right: 0;
	}
	.active {
		border-color: #0047BB;
	}
	.active .line {
		display: block;
	}
	.line {
		display: none;
		position: absolute;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
		width: 2upx;
		height: 40upx;
		background: #0047BB;
		animation: twinkling 1s infinite ease;
	}
	.hide-input {
		position: absolute;
		top: 0;
		left: -100%;
		width: 200%;
		height: 100%;
		text-align: left;
		z-index: 9;
		opacity: 1;
	}
	@keyframes twinkling {
		0% {
			opacity: 0.2;
		}
		50% {
			opacity: 0.5;
		}
		100% {
			opacity: 0.2;
		}
	}
	
	.dot{
		font-size: 80upx;
		line-height: 40upx;
	}
}
</style>
复制代码

效果图

7ddb78b031a4ea2391c1b14d92fbaad.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享