Skip to content

需求

UI 提供一张设计图,如下:

输入 6 位数字密码,每个 input 只能输入一个数字,每次输入完当前 input 框后自动跳转到下一个 input,输入完成后提交数据。

实现

布局 6 个 input 框,使用 keydown 事件监听删除操作,keyup 事件监听输入时操作,输入完当前 input 是否满足需求, 判断是否跳转到下一个 input

html 代码部分:

<div class="input-frame mb10 clearfix">
		<input @keydown.8="deleteVal('input1', 'input1')" @keyup="changeVal($event, 'input1', 'input2')" ref="input1" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input1" type="number" autocomplete="off" />
		<input @keydown.8="deleteVal('input2', 'input1')" @keyup="changeVal($event, 'input2', 'input3')" ref="input2" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input2" type="number" autocomplete="off" />
		<input @keydown.8="deleteVal('input3', 'input2')" @keyup="changeVal($event, 'input3', 'input4')" ref="input3" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input3" type="number" autocomplete="off" />
		<input @keydown.8="deleteVal('input4', 'input3')" @keyup="changeVal($event, 'input4', 'input5')" ref="input4" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input4" type="number" autocomplete="off" />
		<input @keydown.8="deleteVal('input5', 'input4')" @keyup="changeVal($event, 'input5', 'input6')" ref="input5" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input5" type="number" autocomplete="off" />
		<input @keydown.8="deleteVal('input6', 'input5')" @keyup="changeVal($event, 'input6', 'input6')" ref="input6" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input6" type="number" autocomplete="off" />
	</div>
	<div class="tac pt15">
		<p class="p10" style="color:#FC3D39;">{{ errMsg }}</p>
		<button class="btn fs16 btn-theme" @click="saveFreePassword">确定</button>
	</div>
<div class="input-frame mb10 clearfix">
		<input @keydown.8="deleteVal('input1', 'input1')" @keyup="changeVal($event, 'input1', 'input2')" ref="input1" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input1" type="number" autocomplete="off" />
		<input @keydown.8="deleteVal('input2', 'input1')" @keyup="changeVal($event, 'input2', 'input3')" ref="input2" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input2" type="number" autocomplete="off" />
		<input @keydown.8="deleteVal('input3', 'input2')" @keyup="changeVal($event, 'input3', 'input4')" ref="input3" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input3" type="number" autocomplete="off" />
		<input @keydown.8="deleteVal('input4', 'input3')" @keyup="changeVal($event, 'input4', 'input5')" ref="input4" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input4" type="number" autocomplete="off" />
		<input @keydown.8="deleteVal('input5', 'input4')" @keyup="changeVal($event, 'input5', 'input6')" ref="input5" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input5" type="number" autocomplete="off" />
		<input @keydown.8="deleteVal('input6', 'input5')" @keyup="changeVal($event, 'input6', 'input6')" ref="input6" type="text" class="c-fl input-password" maxLength="1" v-model.trim="input6" type="number" autocomplete="off" />
	</div>
	<div class="tac pt15">
		<p class="p10" style="color:#FC3D39;">{{ errMsg }}</p>
		<button class="btn fs16 btn-theme" @click="saveFreePassword">确定</button>
	</div>

删除值时监听当前 input 值,和 上一个 input 值;如果当前 input 值为空,则鼠标光标跳转到上一个 input 框,并清除该 input 值。

输入值时,监听系统事件,当前 input 值,和下一个 input 值,输入完当前 input 值后,鼠标光标自动跳转到下一个 input。输入正确完整后提交数据到后端。

JS 代码部分:

// ...
	data: function() {
		return {
			errMsg: '',
			input1: '',
			input2: '',
			input3: '',
			input4: '',
			input5: '',
			input6: ''
		}
	},
	methods: {
		deleteVal: function(inputval, preInputVal) {
			if(this[inputval].length > 0) {
				this[inputval] = '';
			}else{ //光标跳转到上一个input
				this.$nextTick(function() {
					this.$refs[preInputVal].focus();
					this[preInputVal] = '';
					this[inputval] = '';
				})
			}
			this.errMsg = '';
		},
		changeVal: function(e, inputVal, nextInputVal) { //当前input,下一个input
			this[inputVal] = this[inputVal].replace(/[^\d]{1}/g, '');
			if(this[inputVal].length <= 0) return false;
			if(e.keyCode != 8) {
				this.$nextTick(function() {
					this.$refs[nextInputVal].focus();
					this[inputVal] = (this[inputVal]).toString().slice(-1);
					this.errMsg = '';
				})
			}
		},
		saveFreePassword: function() {
			this.freePassword = this.input1 + this.input2 + this.input3 + this.input4 + this.input5 + this.input6;
			this.freePassword = this.freePassword.replace(/[^\d]/g, '');
 			if(this.freePassword.length != 6) {
				this.errMsg = '※ 密码错误,请确认密码后重新输入';
				return false;
			}
			this.$root.Bus.$emit('freeCoursePassword', { freePassword:  this.freePassword});
		}
	}
// ...
	data: function() {
		return {
			errMsg: '',
			input1: '',
			input2: '',
			input3: '',
			input4: '',
			input5: '',
			input6: ''
		}
	},
	methods: {
		deleteVal: function(inputval, preInputVal) {
			if(this[inputval].length > 0) {
				this[inputval] = '';
			}else{ //光标跳转到上一个input
				this.$nextTick(function() {
					this.$refs[preInputVal].focus();
					this[preInputVal] = '';
					this[inputval] = '';
				})
			}
			this.errMsg = '';
		},
		changeVal: function(e, inputVal, nextInputVal) { //当前input,下一个input
			this[inputVal] = this[inputVal].replace(/[^\d]{1}/g, '');
			if(this[inputVal].length <= 0) return false;
			if(e.keyCode != 8) {
				this.$nextTick(function() {
					this.$refs[nextInputVal].focus();
					this[inputVal] = (this[inputVal]).toString().slice(-1);
					this.errMsg = '';
				})
			}
		},
		saveFreePassword: function() {
			this.freePassword = this.input1 + this.input2 + this.input3 + this.input4 + this.input5 + this.input6;
			this.freePassword = this.freePassword.replace(/[^\d]/g, '');
 			if(this.freePassword.length != 6) {
				this.errMsg = '※ 密码错误,请确认密码后重新输入';
				return false;
			}
			this.$root.Bus.$emit('freeCoursePassword', { freePassword:  this.freePassword});
		}
	}