结合vant框架
效果图
组件页面
<template>
<div class="keyboard">
<div class="keytitle">
请点击选择车牌号
<span>(绿色虚线为新能源)</span>
</div>
<div class="input-box" @click="clickShowKeyboard">
<li>{{ first }}</li>
<li>{{ numArr[0] }}</li>
<li>{{ numArr[1] }}</li>
<li>{{ numArr[2] }}</li>
<li>{{ numArr[3] }}</li>
<li>{{ numArr[4] }}</li>
<li>{{ numArr[5] }}</li>
<li>{{ numArr[6] }}</li>
</div>
<div class="keyqr" @click="close">
确定
</div>
<!-- 选择车牌号 首个汉字键盘 弹出层 -->
<div class="plate_number">
<van-popup
v-model="show_chinese"
position="bottom"
:overlay="true"
overlay-class="displayNone"
>
<div class="plate_chinese_box">
<!-- 点击对应的汉字,进行输入 -->
<van-button
size="small"
v-for="(item, index) in ChineseList"
:key="item.id"
@click="checkChinese(index)"
>{{ item.name }}</van-button
>
<div class="close-box" @click.stop="close_keyboard">
<div>╳</div>
<li></li>
</div>
</div>
</van-popup>
</div>
<!-- 英文 数字 键盘 -->
<div class="allBoard">
<van-popup
v-model="show_allBoard"
position="bottom"
:overlay="true"
overlay-class="displayNone"
>
<div class="plate_number_box">
<!-- 点击对应的字母或数字,进行输入 -->
<van-button
size="small"
v-for="(item, index) in English_Number"
:key="item.id"
@click="checkEnglish_num(index)"
>{{ item.name }}</van-button
>
<div class="close-box" @click.stop="close_keyboard">
<div>╳</div>
<li></li>
</div>
</div>
</van-popup>
</div>
</div>
</template>
<script>
export default {
props: ["showShare"],
watch: {
showShare() {
console.log("组件页", this.showShare);
this.show_chinese = this.showShare;
}
},
data() {
return {
showKeyboard: true, //车牌号输入框是否聚焦
show_chinese: false, //是否显示汉字键盘
show_allBoard: false, //是否显示英文数字键盘
ChineseList: [
{ name: "京", id: 1 },
{ name: "津", id: 2 },
{ name: "冀", id: 3 },
{ name: "晋", id: 4 },
{ name: "蒙", id: 5 },
{ name: "辽", id: 6 },
{ name: "吉", id: 7 },
{ name: "黑", id: 8 },
{ name: "沪", id: 9 },
{ name: "苏", id: 10 },
{ name: "浙", id: 11 },
{ name: "皖", id: 12 },
{ name: "闽", id: 13 },
{ name: "赣", id: 14 },
{ name: "鲁", id: 15 },
{ name: "豫", id: 16 },
{ name: "鄂", id: 17 },
{ name: "湘", id: 18 },
{ name: "粤", id: 19 },
{ name: "桂", id: 20 },
{ name: "琼", id: 21 },
{ name: "渝", id: 22 },
{ name: "川", id: 23 },
{ name: "贵", id: 24 },
{ name: "云", id: 25 },
{ name: "藏", id: 26 },
{ name: "陕", id: 27 },
{ name: "甘", id: 28 },
{ name: "青", id: 29 },
{ name: "宁", id: 30 },
{ name: "新", id: 31 },
{ name: "←", id: 99 }
],
English_Number: [
{ name: "1", id: 28 },
{ name: "2", id: 29 },
{ name: "3", id: 30 },
{ name: "4", id: 31 },
{ name: "5", id: 32 },
{ name: "6", id: 33 },
{ name: "7", id: 34 },
{ name: "8", id: 35 },
{ name: "9", id: 36 },
{ name: "0", id: 37 },
{ name: "Q", id: 38 },
{ name: "W", id: 39 },
{ name: "E", id: 40 },
{ name: "R", id: 41 },
{ name: "T", id: 42 },
{ name: "Y", id: 43 },
{ name: "U", id: 44 },
{ name: "I", id: 45 },
{ name: "O", id: 46 },
{ name: "P", id: 47 },
{ name: "A", id: 48 },
{ name: "S", id: 49 },
{ name: "D", id: 50 },
{ name: "F", id: 51 },
{ name: "G", id: 52 },
{ name: "H", id: 53 },
{ name: "J", id: 54 },
{ name: "K", id: 55 },
{ name: "L", id: 56 },
{ name: "Z", id: 57 },
{ name: "X", id: 58 },
{ name: "C", id: 59 },
{ name: "V", id: 60 },
{ name: "B", id: 61 },
{ name: "N", id: 62 },
{ name: "M", id: 63 },
{ name: "←", id: 99 }
],
plate_number: "", //车牌号
first: "",
numArr: []
};
},
methods: {
// 唤起键盘
clickShowKeyboard() {
if (!this.first) {
this.show_chinese = true;
} else {
this.show_chinese = false;
this.show_allBoard = true;
}
},
// 选择车牌号前面的汉字
checkChinese(index) {
// 如果点击删除键,删除第一个格的内容
if (this.ChineseList[index].id == 99) {
this.first = "";
} else {
// 把选中的字赋值给第一个格,并且切换键盘
this.first = this.ChineseList[index].name;
this.show_chinese = false;
this.show_allBoard = true;
}
this.hao = this.first + this.numArr.join("");
this.$emit("sendmsg", this.hao);
// console.log("ddddddddd", this.hao);
},
// 选择车牌号后面的数字和字母
checkEnglish_num(index) {
// 如果点击删除键,删除 numArr 的最后一个值
if (this.English_Number[index].id == 99) {
this.numArr.pop();
// 如果 numArr 里面被删的没有值了,切换键盘
if (this.numArr.length == 0) {
this.show_chinese = true;
this.show_allBoard = false;
}
} else {
// 把选中的值 push 到 numArr 内
this.numArr.push(this.English_Number[index].name);
// 如果 numArr 中的值超过 7 个(车牌号的最大位数),删除最后一个
if (this.numArr.length > 7) {
this.numArr.pop();
}
}
// 把牌照拼接起来赋值到info
this.hao = this.first + this.numArr.join("");
// console.log("ddddddddd", this.hao);
this.$emit("sendmsg", this.hao);
},
// 关闭虚拟键盘
close_keyboard() {
this.show_chinese = false;
this.show_allBoard = false;
this.$emit("jiantingClose", "(组件)我被执行了");
},
close() {
this.show_chinese = false;
this.show_allBoard = false;
this.$emit("qbClose", "(组件)我被执行了");
}
}
};
</script>
<style scoped lang="scss">
.keytitle {
text-align: center;
font-size: 1.4rem;
color: black;
margin-bottom: 1.4rem;
span {
display: block;
color: #35b784;
font-size: 1rem;
margin-top: 0.5rem;
}
}
.keyqr {
text-align: center;
font-size: 1.4rem;
margin-top: 1.4rem;
background: #3f51b5;
width: 80%;
margin: 0 auto;
border-radius: 6px;
color: #fff;
padding: 0.5rem 0;
}
.keyboard {
width: 100%;
// position: absolute;
z-index: 999;
margin-top: 9rem;
}
// 车牌号 & 虚拟键盘
.input-box {
width: 21rem;
height: 3.2rem;
margin: auto;
background: #fff;
box-shadow: 0px 6px 8px 0px rgba(96, 100, 112, 0.1);
border-radius: 0.4rem;
// border-bottom: 1px solid rgba(206, 208, 210, 1);
border: 1px solid #ced0d2;
margin: 0 auto 2rem;
display: flex;
justify-content: center;
li {
flex: 1;
border-right: 1px solid rgba(206, 208, 210, 1);
box-sizing: border-box;
margin-left: -1px;
font-size: 1.5rem;
display: flex;
align-items: center;
justify-content: center;
color: #111f85;
&:nth-child(7) {
border: none;
}
}
li:last-child {
border: 2px dotted #35b784;
}
}
.class-close-box {
width: 2rem;
height: 1.5rem;
position: absolute;
right: 0.5rem;
top: -3.3rem;
}
.class-close-box-div {
width: 2rem;
height: 2rem;
font-size: 2rem;
line-height: 2rem;
margin: auto;
text-align: center;
border: 1px solid #666;
border-radius: 50%;
}
.class-close-box-li {
width: 1px;
height: 1rem;
background: #666;
margin: auto;
}
.overflow-y {
overflow-y: inherit;
}
.class-van-button-small {
min-width: 0;
border-radius: 5px;
margin: 5px 2px;
box-shadow: 5px 5px 5px #aaa;
}
.class-plate-box {
width: 100%;
padding: 0.7rem 0.5rem;
box-sizing: border-box;
background: #eaf1f9;
position: relative;
}
.plate_number {
.van-popup {
@extend .overflow-y;
}
.van-popup--bottom {
background: #eee;
}
.plate_chinese_box {
width: 100%;
@extend .class-plate-box;
.close-box {
@extend .class-close-box;
div {
@extend .class-close-box-div;
}
li {
@extend .class-close-box-li;
}
}
.van-button--small {
width: 11.3%;
height: 3.5rem;
font-size: 1.1rem;
@extend .class-van-button-small;
}
}
}
.allBoard {
.van-popup {
@extend .overflow-y;
}
.plate_number_box {
width: 100%;
@extend .class-plate-box;
.close-box {
@extend .class-close-box;
div {
@extend .class-close-box-div;
}
li {
@extend .class-close-box-li;
}
}
.van-button--small {
width: 8.8%;
height: 3rem;
font-size: 1.1rem;
@extend .class-van-button-small;
}
.van-button--small:nth-child(1) {
margin-bottom: 5px;
}
.van-button--small:nth-child(21) {
margin-left: 5%;
}
.van-button--small:nth-child(30) {
margin-left: 10%;
}
.van-button--small:last-child {
width: 13%;
}
}
}
</style>
<style lang="scss">
.displayNone {
display: none !important;
}
</style>
页面调用
<template>
<div>
<div class="bangding addcar">
<van-form @submit="onSubmit">
<van-field
v-model="licensePlateNumber"
name="licensePlateNumber"
label="车牌号"
placeholder="请填写车牌号"
@input="vinInput"
@click="showSharefn"
readonly
:rules="[{ validator, message: '请选择正确的车牌号' }]"
>
</van-field>
<van-field name="switchChecked" label="默认" class="mr">
<template #input>
<van-switch
:active-value="1"
:inactive-value="0"
v-model="switchChecked"
size="20"
/>
</template>
</van-field>
<div class="tj">
<van-button round block type="info" native-type="submit"
>确定</van-button
>
</div>
</van-form>
</div>
<van-popup
v-model="show"
closeable
position="bottom"
:style="{ height: '100%' }"
>
<v-jianpan
@sendmsg="getmsg"
:showShare="showShare"
@jiantingClose="zhixinClose"
@qbClose="gbtc"
></v-jianpan>
</van-popup>
</div>
</template>
<script>
import { Toast } from "vant";
import API from "@/api/api.js";
import jianpan from "@/components/jianpan.vue";
export default {
data() {
return {
show: false,
licensePlateNumber: "",
switchChecked: "0",
showShare: false
};
},
created() {},
components: {
"v-jianpan": jianpan
},
methods: {
gbtc() {
this.showShare = false;
this.show = false;
},
getmsg(val) {
// console.log("666666", val);
this.licensePlateNumber = val;
},
showSharefn() {
// this.showShare = true;
this.show = true;
// console.log("aaaaaaaaaaaaa");
},
zhixinClose(e) {
// console.log(e, "aaaaaaaaaaaaa");
this.showShare = false;
},
validator(val) {
const plateNumber = /^([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1})$/;
return plateNumber.test(val);
},
onSubmit(val) {
},
}
};
</script>