先看下效果如下:
动态图如下
uniapp的keyup获取不到keyCode和compositionstart,compositionend,所以需要监听input节点的keyup事件,
思路以及代码如下:
1.将每一个字符用文本框输入,代码如下
html
<view class="license-input">
<input type="text" class="input-code code0" />
<input type="text" class="input-code code1" />
...
</view>
2.初始化的时候将input下的真是inputdom绑定keyup事件调用skipnext,并传入每一个input的index,同时绑定compositionstart和compositionend
js
mounted(){
document.querySelectorAll(".input-code").forEach((el, index) => {
const input = el.querySelector("input");
if (index > 0) {
input.disabled = true;
}
input.addEventListener("keyup", (event) => {
this.skipnext(index, event);
});
input.addEventListener("compositionstart", this.inputstart);
input.addEventListener("compositionend", this.inputend);
});
}
3.对按键进行处理,如果当前文本框已经输入完成则跳转到下一个文本框,如果没有则停留在当前文本框,第一次输入的时候,前面的没有输入完成,则不可跳过前面的号码去输入后面的号码,当删除后则解除禁止
完整代码如下:
新建license-input.vue文件,
html
<template>
<view class="license-input">
<input type="text" class="input-code code0" />
<input type="text" class="input-code code1" />
<span class="dian">·</span>
<input type="tel" class="input-code code2" />
<input type="tel" class="input-code code3" />
<input type="tel" class="input-code code4" />
<input type="tel" class="input-code code5" />
<input type="tel" class="input-code code6" />
</view>
</template>
<script>
/**
* 车牌照输入
* ===== 使用场景 ======
* 下单页面ETC
*
*/
export default {
name: "license-input",
props: {
carvalue: {
type: String,
default: "",
},
},
mounted() {
this.setEvent();
},
methods: {
setEvent() {
const v = this.carvalue.split("");
document.querySelectorAll(".input-code").forEach((el, index) => {
const input = el.querySelector("input");
input.value = v[index] || "";
if (index > 0) {
input.disabled = true;
}
input.addEventListener("keyup", (event) => {
this.skipnext(index, event);
});
input.addEventListener("compositionstart", this.inputstart);
input.addEventListener("compositionend", this.inputend);
});
this.$emit("input", this.carvalue);
},
getVal() {
let val = "";
document.querySelectorAll(".input-code").forEach((el, index) => {
val += el.querySelector("input").value;
});
return val;
},
skipnext(num, e) {
const keycode = e.keyCode || e.which;
if (e.target.timer) {
clearTimeout(e.target.timer);
e.target.timer = null;
}
// tab,ctrl,回车,Enter等可自定排除
if (keycode == 9 || keycode == 13 || keycode == 18 || keycode == 32) {
return;
}
//删除按键
if (keycode == 8) {
if (num > 0 && !e.target.value) {
const prevel = document.querySelector(`.code${num - 1}`).querySelector("input");
// e.target.disabled = true; // 删除后将disabled 设置为true
prevel.focus();
}
this.$emit("input", this.getVal());
return;
}
if (num < 6 && !e.target.hascom) {
const nextel = document.querySelector(`.code${num + 1}`).querySelector("input");
// 添加延迟,防止过快输入。
e.target.timer = setTimeout(() => {
nextel.disabled = false;
nextel.focus();
}, 300);
}
// 只能输入一个字符
if (e.target.value.length > 1 && !e.target.hascom) {
e.target.value = e.target.value.substr(e.target.value.length-1, 1);
}
this.$emit("input", this.getVal());
},
inputstart(e) {
e.target.hascom = true;
},
inputend(e) {
e.target.hascom = false;
},
},
};
</script>
<style>...</style>
父组件使用
js
<license-input carvalue="浙A12345" @input="(e) => {carmodel = e}"></license-input>
车牌为:{{carmodel }}
import licenseInput from "@/components/license-input.vue";