vue移动端车牌号输入键盘组件封装(支持新能源车牌和uniapp)
支持点击输入框删除或输入车牌,可直接在uniapp项目中运行,将view标签换为div、并且将rpx单位换成px可在vue项目里运行。
·
一、效果图
二、说明
支持点击输入框删除或输入车牌,可直接在uniapp项目中运行,将view标签换为div、并且将rpx单位换成px可在vue项目里运行
三、代码
<template>
<view class="containers">
<view class="parking-box">
农批市场
</view>
<view class="car_input_box">
<view>请输入正确的车牌</view>
<view class="car_number_input">
<view class="car_type">
<view class="default_car" :class="{active_car : activeNum == '0'}"
@click="chooseNumber(carNumber[0],'0')">
<view class="" v-show="carNumber[0]">
{{carNumber[0]}}
</view>
</view>
<view class="default_car default_car1" :class="{active_car: activeNum == '1'}"
@click="chooseNumber(carNumber[1],'1')">
<view class="" v-show="carNumber[1]">
{{carNumber[1]}}
</view>
</view>
<view class="default_dot"></view>
<view class="default_car" :class="{active_car:activeNum == '2'}"
@click="chooseNumber(carNumber[2],'2')">
<view class="" v-show="carNumber[2]">
{{carNumber[2]}}
</view>
</view>
<view class="default_car" :class="{active_car : activeNum == '3'}"
@click="chooseNumber(carNumber[3],'3')">
<view class="" v-show="carNumber[3]">
{{carNumber[3]}}
</view>
</view>
<view class="default_car" :class="{active_car : activeNum == '4'}"
@click="chooseNumber(carNumber[4],'4')">
<view class="" v-show="carNumber[4]">
{{carNumber[4]}}
</view>
</view>
<view class="default_car" :class="{active_car : activeNum == '5'}"
@click="chooseNumber(carNumber[5],'5')">
<view class="" v-show="carNumber[5]">
{{carNumber[5]}}
</view>
</view>
<view class="default_car" :class="{active_car : activeNum == '6'}"
@click="chooseNumber(carNumber[6],'6')">
<view class="" v-show="carNumber[6]">
{{carNumber[6]}}
</view>
</view>
<view class="default_car"
:class="{diabled_car:currentIndex != 1,active_car:activeNum == '7' && currentIndex == 1}"
@click="chooseNumber(carNumber[7],'7')">
<view class="" v-show="carNumber[7]">
{{carNumber[7]}}
</view>
</view>
</view>
</view>
<view class="check_energy">
<view>
<img src="../../static/img/duoxuan_weixuan.png" alt="" v-if="currentIndex == 1"
@click="chooseIsNewEnergy">
<img src="../../static/img/duoxuanwei.png" alt="" v-else @click="chooseIsNewEnergy">
</view>
<view>新能源车牌号</view>
</view>
<view class="confirm_btn" @click="submit">
确认
</view>
</view>
<view class="tips">
注: 请认真核对车牌,以免支付错误!
</view>
<!-- 键盘 -->
<view class="keyboard-content">
<!-- 省份键盘 -->
<template v-if="provinceBoardShow">
<view style="position: relative;">
<view class="province-keyboard flex jus-center">
<view class="td-nor color-333 province-td" v-for="(item,index) in provincesKeyList" :key="index"
@click="provinceKeyClick(item,index)" hover-class="board-active" hover-start-time="0"
hover-stay-time="80">
<view class="province-font">
{{item}}
</view>
</view>
</view>
<view class="province-keyboard flex jus-center">
<view class="td-nor color-333 province-td" v-for="(item,index) in provincesKeyTwo" :key="index"
@click="provinceKeyClick(item,index)" hover-class="board-active" hover-start-time="0"
hover-stay-time="80">
<view class="province-font">
{{item}}
</view>
</view>
</view>
<view class="province-keyboard flex jus-center">
<view class="td-nor color-333 province-td" v-for="(item,index) in provincesKeyThree"
:key="index" @click="provinceKeyClick(item,index)" hover-class="board-active"
hover-start-time="0" hover-stay-time="80">
<view class="province-font">
{{item}}
</view>
</view>
</view>
<view class="province-keyboard flex">
<view class="td-nor color-333 province-td" v-for="(item,index) in provincesKeyFour" :key="index"
@click="provinceKeyClick(item,index)" hover-class="board-active" hover-start-time="0"
hover-stay-time="80">
<view class="province-font">
{{item}}
</view>
</view>
</view>
<view @click.stop="backspace" class="delete flex del-province">
<img src="../../static/img/del@2x.png" class="del-con" alt="">
</view>
</view>
</template>
<!--数字键盘-->
<template v-if="!provinceBoardShow">
<view class="number-keyboard flex between">
<template>
<view class="td td-num color-333" :class="numberIsDis ? 'board-active' : ''"
v-for="(item,index) in numberKeyList" :key="index" @click="numberKeyClick(item,index)"
:hover-class="numberIsDis ? '' : 'board-active'" hover-start-time="0" hover-stay-time="80">
{{item}}
</view>
</template>
</view>
</template>
<!--字母键盘-->
<template v-if="!provinceBoardShow">
<view class="english-keyboard flex between">
<template>
<view class="td td-num color-333" :class="englishIsDis ? 'board-active' : ''"
v-for="(item,idx) in englishKeyOneList" :key="idx" @click="englishKeyClick(item,idx)"
:hover-class="englishIsDis ? '' : 'board-active'" hover-start-time="0" hover-stay-time="80">
{{item}}
</view>
</template>
</view>
<!-- 最后一行 -->
<view class="english-keyboard flex between">
<template>
<view class="td td-num color-333" :class="englishIsDis ? 'board-active' : ''"
v-for="(item,index) in englishKeyTwoList" :key="index" @click="englishKeyClick(item,index)"
:hover-class="englishIsDis ? '' : 'board-active'" hover-start-time="0" hover-stay-time="80">
{{item}}
</view>
</template>
<!-- 挂字键 -->
<template>
<!-- <view @click="trailerFiledClick('港')" class="td td-num color-333"
:class="trailerFiledIsDis ? 'board-active' : ''"
:hover-class="trailerFiledIsDis ? '' : 'board-active'" hover-start-time="0"
hover-stay-time="80">港</view> -->
<view @click="trailerFiledClick('澳')" class="td td-num color-333"
:class="trailerFiledIsDis ? 'board-active' : ''"
:hover-class="trailerFiledIsDis ? '' : 'board-active'" hover-start-time="0"
hover-stay-time="80">澳</view>
<view @click="trailerFiledClick('学')" class="td td-num color-333"
:class="trailerFiledIsDis ? 'board-active' : ''"
:hover-class="trailerFiledIsDis ? '' : 'board-active'" hover-start-time="0"
hover-stay-time="80">学</view>
<view @click="trailerFiledClick('挂')" class="td td-num color-333"
:class="trailerFiledIsDis ? 'board-active' : ''"
:hover-class="trailerFiledIsDis ? '' : 'board-active'" hover-start-time="0"
hover-stay-time="80">挂</view>
<view @click="trailerFiledClick('警')" class="td td-num color-333"
:class="trailerFiledIsDis ? 'board-active' : ''"
:hover-class="trailerFiledIsDis ? '' : 'board-active'" hover-start-time="0"
hover-stay-time="80">警</view>
</template>
<view @click.stop="backspace" class="delete flex">
<img src="../../static/img/del@2x.png" class="del-con" alt="">
</view>
</view>
</template>
</view>
</view>
</template>
<script>
export default {
name: "add-car-input",
data() {
return {
current: 0,
carNumber: [],
carTypeList: [{
text: '新能源',
value: 1,
}],
currentIndex: 0,
provincesKeyList: '京津冀晋蒙辽吉黑',
provincesKeyTwo: '沪苏浙皖闽赣鲁豫',
provincesKeyThree: '鄂湘粤桂琼渝川贵',
provincesKeyFour: '云藏陕甘青宁新',
provinceBoardShow: true, // 省键盘
numberKeyList: '1234567890',
numberIsDis: true, // 输入键盘不可点击 true为不可点击
englishIsDis: false, // 字母键盘可点击
englishKeyOneList: 'ABCDEFGHJKLMNPQRSTUV',
englishKeyTwoList: 'WXYZ',
trailerFiledIsDis: true, // 挂字禁用
activeNum: '0',
isClickCarNum: false,
isCheckEnergy: false,
};
},
watch: {
'carNumber.length': {
handler(newVal, oldValue) {
console.log(newVal, oldValue, 'newVal, oldValue')
this.setTrailerKeyboardDis()
},
deep: true
}
},
methods: {
// 确定按钮
submit() {
//普通车车牌校验
const carCardP =
/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/;
//新能源车牌校验
const carCardD =
/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/;
let carPlate = this.carNumber.join('')
console.log(this.carNumber, carPlate, 'carNumber')
if (this.carNumber.length == 0) {
uni.showToast({
title: '请输入车牌号',
icon: 'none',
duration: 2000
})
return;
}
if (!carCardP.test(carPlate) && (this.currentIndex == 0)) {
// 普通车
uni.showToast({
title: '车牌号输入有误',
icon: 'none',
duration: 2000
})
return;
}
if (!carCardD.test(carPlate) && this.currentIndex == 1) {
// 新能源
uni.showToast({
title: '车牌号输入有误',
icon: 'none',
duration: 2000
})
return;
}
},
// 点击车牌号输入框
chooseNumber(item, active) {
console.log(item, active, 'itemsss')
if (active == 1) {
// 第二位
this.numberIsDis = true
this.provinceBoardShow = false
} else if (active == '0') {
// 第一位
this.provinceBoardShow = true
this.numberIsDis = true
} else {
this.numberIsDis = false
this.provinceBoardShow = false
}
if (this.currentIndex == 0 && active == '7') {
// 普通车牌 不让点击一位
} else {
this.activeNum = active
this.current = active
this.isClickCarNum = true
}
if ((this.currentIndex == 0 && this.carNumber.length >= 6 && this.current >= 6) || (this.currentIndex ==
1 && this.carNumber
.length >= 7 && this.current >= 7)) {
this.trailerFiledIsDis = false;
} else {
this.trailerFiledIsDis = true;
}
},
// 点击新能源或者普通车
chooseIsNewEnergy() {
console.log(this.carNumber, '切换新能源')
if (this.currentIndex == 1) {
this.currentIndex = 0
if (this.carNumber.length == 8) {
this.carNumber.pop()
}
} else {
this.currentIndex = 1
if (this.carNumber.length == 7) {
this.current = 7
this.activeNum = 7
}
}
console.log(this.carNumber, '切换新能源后')
this.$forceUpdate()
},
// 省份键盘
provinceKeyClick(val, index) {
console.log(this.currentIndex, this.carNumber.length, 'this.carNumber.length省')
this.carNumber[0] = val
this.provinceBoardShow = false
this.numberIsDis = true;
this.englishIsDis = false;
this.current++
this.activeNum = this.current
this.$forceUpdate()
console.log(this.current, 'current')
},
// 数字键盘
numberKeyClick(val, idx) {
let flag = this.carNumber.indexOf("") === -1
console.log(this.currentIndex, this.carNumber, flag, this.carNumber.length, 'this.carNumber.length数字')
if (this.numberIsDis) return
if ((this.currentIndex == 0 && this.carNumber.length >= 7 && this.current >= 7) || (this.currentIndex ==
1 && this.carNumber.length >= 8 && this.current >= 8)) {
return
}
console.log(111)
this.current++
this.carNumber[this.current - 1] = val;
this.setTrailerKeyboardDis()
this.$forceUpdate()
this.activeNum = this.current
this.numberIsDis = false
console.log(this.current, 'current')
console.log(this.currentIndex, this.carNumber, flag, this.carNumber.length, 'this.carNumber.length数字后')
},
// 字母键盘
englishKeyClick(val, idx) {
let flag = this.carNumber.indexOf("") === -1
console.log(this.currentIndex, this.carNumber, flag, this.carNumber.length, 'this.carNumber.length字母')
// this.activeNum = this.carNumber.length
if (this.englishIsDis) return
if ((this.currentIndex == 0 && this.carNumber.length >= 7 && this.current >= 7) || (this.currentIndex ==
1 && this.carNumber.length >= 8 && this.current >= 8)) {
return
}
console.log(222)
this.current++
this.carNumber[this.current - 1] = val;
console.log(this.current, 'this.current 字母键盘')
if (this.current == 2) this.numberIsDis = false;
this.setTrailerKeyboardDis()
this.$forceUpdate()
this.activeNum = this.current
this.numberIsDis = false
console.log(this.current, 'current')
console.log(this.currentIndex, this.carNumber, flag, this.carNumber.length, 'this.carNumber.length字母后')
},
// 设置挂车键盘禁用(只能最后一个选择挂)
setTrailerKeyboardDis() {
if ((this.currentIndex == 0 && this.carNumber.length >= 6 && this.current >= 6) || (this.currentIndex ==
1 && this.carNumber
.length >= 7 && this.current >= 7)) {
this.trailerFiledIsDis = false;
} else {
this.trailerFiledIsDis = true;
}
},
// 点击挂字
trailerFiledClick(val) {
console.log(val, this.trailerFiledIsDis, '挂字')
if (this.trailerFiledIsDis) return
if ((this.currentIndex == 0 && this.carNumber.length >= 7 && this.current >= 7) || (this.currentIndex ==
1 && this.carNumber.length >= 8 && this.current >= 8)) {
console.log(111222)
return
}
this.current++
this.carNumber[this.current - 1] = val;
this.activeNum = this.current
this.$forceUpdate()
console.log(this.carNumber, this.current, 'gua')
},
// 删除键
backspace() {
console.log(this.current, 'current')
if (this.current < 0) return
if (this.current == 0) {
this.provinceBoardShow = true
this.activeNum = 0
this.carNumber[0] = ''
console.log(this.carNumber[0], 'this.carNumber[0]')
this.$forceUpdate()
return
// this.numberIsDis = true
// this.englishIsDis = true
// this.trailerFiledIsDis = true
} else if (this.current == 1) {
this.provinceBoardShow = true
this.activeNum = 1
this.carNumber[1] = ''
} else if (this.current == 2) {
this.provinceBoardShow = false
this.numberIsDis = true
this.carNumber[this.current] = ''
} else {
this.provinceBoardShow = false
this.carNumber[this.current - 1] = ''
}
if ((this.currentIndex == 0 && this.current <= 6) || (this.currentIndex == 1 && this.current <= 7)) {
this.trailerFiledIsDis = true;
} else {
this.trailerFiledIsDis = false;
}
this.current--
this.activeNum = this.current
this.$forceUpdate()
console.log(this.carNumber, '删除后车牌号')
},
}
}
</script>
<style lang="scss" scoped>
.containers {
box-sizing: border-box;
}
.parking-box {
width: 100%;
height: 254rpx;
background: linear-gradient(180deg, #11B690 0%, #11B690 100%);
font-size: 44rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #FFFFFF;
text-align: center;
padding-top: 52rpx;
box-sizing: border-box;
}
.car_input_box {
width: 702rpx;
height: 440rpx;
background: #FFFFFF;
box-shadow: 0rpx 4rpx 40rpx 0rpx rgba(0, 0, 0, 0.06);
border-radius: 12rpx;
margin: -86rpx auto 0;
font-size: 32rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
text-align: center;
padding: 40rpx 20rpx;
box-sizing: border-box;
}
@keyframes fade {
from {
opacity: 1.0;
}
50% {
opacity: 0;
}
to {
opacity: 1.0;
}
}
@-webkit-keyframes fade {
from {
opacity: 1.0;
}
50% {
opacity: 0;
}
to {
opacity: 1.0;
}
}
.flex {
display: flex;
}
.between {
justify-content: space-between;
align-items: center;
}
.font-30 {
font-size: 30rpx;
}
.color-333 {
color: #333333;
}
.car_type {
display: flex;
justify-content: space-between;
margin: 0 auto;
width: 100%;
align-items: center;
}
.default_car {
width: 72rpx;
height: 94rpx;
background: #FFFFFF;
border-radius: 4rpx;
border: 2rpx solid rgba(0, 0, 0, 0.1);
text-align: center;
line-height: 94rpx;
font-size: 40rpx;
font-weight: bold;
color: #333333;
}
.line {
color: #EA4070;
border-radius: 2rpx;
animation: fade 1500ms infinite;
-webkit-animation: fade 1500ms infinite;
}
.car_type_box {
display: flex;
justify-content: start;
width: 390rpx;
margin: 0 auto;
}
.car_type_item {
width: 130rpx;
height: 69rpx;
border: 1px solid #999999;
text-align: center;
line-height: 69rpx;
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 500;
color: #999999;
}
.check_energy {
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #6D7278;
display: flex;
justify-content: flex-end;
margin-top: 16rpx;
}
.check_energy img {
width: 32rpx;
height: 32rpx;
margin-right: 8rpx;
}
.car_type_item:nth-child(1) {
border-radius: 6rpx 0rpx 0rpx 6rpx;
border-right: 0.5rpx solid #999999;
}
.car_type_item:nth-child(2) {
border-right: none;
border-left: none;
}
.car_type_item:nth-child(3) {
border-radius: 0rpx 6rpx 6rpx 0rpx;
}
.active {
width: 130rpx;
height: 69rpx;
border: 1px solid #999999;
text-align: center;
line-height: 69rpx;
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 500;
font-weight: bold;
color: #EA4070;
background: rgba(#EA4070, .1);
}
.active:nth-child(1) {
border-radius: 6rpx 0rpx 0rpx 6rpx;
border-right: 0.5rpx solid #999999;
}
.active:nth-child(2) {
border-right: none;
border-left: none;
}
.active:nth-child(3) {
border-radius: 0rpx 6rpx 6rpx 0rpx;
}
.car_number_input {
margin-top: 40rpx;
}
.tips {
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #6D7278;
margin: 16rpx 24rpx;
}
.add_car_box {
width: calc(100% - 64rpx);
height: 80rpx;
background: linear-gradient(180deg, #DF4270, #F299AB);
border-radius: 40rpx;
margin: 0 auto;
}
.add_car {
height: 100%;
line-height: 80rpx;
font-size: 34rpx;
font-weight: 500;
color: #FFFFFF;
text-align: center;
}
.dis_car {
height: 100%;
line-height: 80rpx;
font-size: 34rpx;
font-weight: 500;
color: #FFFFFF;
background: #999999;
text-align: center;
border-radius: 40px;
}
.keyboard-content {
width: 100%;
height: 470rpx;
box-sizing: border-box;
position: fixed;
bottom: 0;
left: 0;
background-color: rgba(205, 208, 212, 0.92);
padding-top: 13rpx;
}
.td {
font-family: "PingFangSC";
font-size: 34rpx;
color: #333333;
font-weight: 500;
margin: 12rpx 1rpx;
background: #FCFCFE;
box-shadow: 0rpx 2rpx 0rpx 0rpx #898A8D;
border-radius: 9rpx;
height: 84rpx;
line-height: 84rpx;
text-align: center;
background-color: #fff;
}
.province-keyboard {
margin: 0 5rpx;
padding: 0 10rpx;
// flex-wrap: wrap;
}
.td-nor {
// flex: 0 1 9%;
// margin-right: 3px;
}
.number-keyboard {
margin: 0 5rpx;
}
.board-active {
box-shadow: 0 0 0 #e5e5e5;
background: #e5e5e5;
}
.english-keyboard {
margin: 0 5rpx;
flex-wrap: wrap;
}
.td-num {
flex: 0 1 9%;
}
.board-active {
box-shadow: 0 0 0 #e5e5e5;
background: #e5e5e5;
}
.delete {
width: 144rpx;
height: 88rpx;
text-align: center;
background-color: #AAADB7;
border-radius: 8rpx;
// position: absolute;
// right: 8rpx;
// bottom: 30rpx;
justify-content: center;
align-items: center;
box-shadow: 0rpx 2rpx 0rpx 0rpx #898A8D;
}
.del-province {
position: absolute;
right: 28rpx;
bottom: 13rpx;
width: 64rpx;
box-shadow: 0rpx 2rpx 0rpx 0rpx #898A8D;
border-radius: 9rpx;
font-family: "PingFangSC";
font-size: 34rpx;
color: #333333;
font-weight: 500;
// margin: 12rpx auto;
background: #FCFCFE;
box-shadow: 0rpx 2rpx 0rpx 0rpx #898A8D;
border-radius: 9rpx;
height: 84rpx;
line-height: 84rpx;
text-align: center;
background: #AAADB7;
}
.sure {
width: 100rpx;
height: 84rpx;
text-align: center;
background-color: #AFB2BC;
border-radius: 8rpx;
position: absolute;
right: 10rpx;
bottom: 30rpx;
justify-content: center;
align-items: center;
}
.default_dot {
width: 8rpx;
height: 8rpx;
background: #333333;
margin: 0 4rpx;
}
.del-con {
width: 44rpx;
height: 32rpx;
}
.jus-center {
justify-content: center;
}
.diabled_car {
background: #F5F5F5;
border-radius: 4rpx;
border: 2rpx solid rgba(0, 0, 0, 0.1);
}
.active_car {
border-radius: 4rpx;
border: 2rpx solid #375DE9;
}
.province-mr {
margin-right: 10rpx;
}
.confirm_btn {
width: 662rpx;
height: 92rpx;
line-height: 92rpx;
background: #11B690;
font-size: 32rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #FFFFFF;
border-radius: 46rpx;
margin-top: 40rpx;
}
.province-td {
width: 12.5%;
}
.province-font {
width: 64rpx;
box-shadow: 0rpx 2rpx 0rpx 0rpx #898A8D;
border-radius: 9rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-size: 34rpx;
color: #000;
font-weight: 500;
margin: 12rpx auto;
box-shadow: 0rpx 2rpx 0rpx 0rpx #898A8D;
border-radius: 9rpx;
height: 84rpx;
line-height: 84rpx;
text-align: center;
background-color: #fff;
}
.confirm-cash-box {
width: 100vh;
height: 100vh;
background-color: rgba(0, 0, 0, 0.7);
position: fixed;
top: 0;
left: 50%;
transform: translateX(-50%);
z-index: 99;
}
.cash-box {
width: 570rpx;
//height: 300px;
background: rgb(223, 223, 223);
border-radius: 28rpx;
margin: 30vh auto 0;
text-align: center;
min-height: 200rpx;
}
.cash-title {
font-size: 34rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
padding-top: 38rpx;
margin: 0 0 24rpx;
}
.content-cash {
font-size: 26rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
margin-bottom: 54rpx;
padding: 0 32rpx;
}
.line-cash {
width: 100%;
height: 1rpx;
background: rgba(60, 60, 67, 0.29);
}
.cancel-box {
width: 100%;
height: 88rpx;
line-height: 88rpx;
color: #11B690;
font-size: 32rpx;
text-align: center;
}
.flex-btwn {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>
更多推荐
已为社区贡献1条内容
所有评论(0)