《uniApp-车牌号选择组件(包含键盘)》

《uniApp-车牌号选择组件(包含键盘)》
一清三白使用 UniApp 实现车牌号选择组件(含键盘和新能源支持)
在移动应用开发中,车牌号输入是一个常见需求,尤其是在与交通、停车、违章查询等相关的应用中。与普通文本输入不同,车牌号输入有着特定的规则和格式,需要专门的键盘和交互设计。本文将详细介绍如何使用 UniApp 框架实现一个功能完善的车牌号选择组件,支持常规车牌和新能源车牌。
效果预览
功能特点
- 支持普通车牌和新能源车牌输入
- 自定义键盘,分为省份简称键盘和字母数字键盘
- 智能切换键盘类型
- 支持车牌号规则限制(如第二位只能输入字母或数字等)
- 集成删除和关闭功能
- 支持初始化已有车牌号
- 优雅的样式和流畅的交互体验
实现思路
- 创建车牌号输入框组件
- 实现省份简称键盘
- 实现字母数字键盘
- 添加车牌号输入规则和限制
- 实现键盘切换和交互逻辑
代码实现
完整代码
- 在components下建立car-number-input文件 复制以下代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316<template>
<view>
<view class="car-input-container">
<view class="car-input-box"
v-for="(item,index) in inputList" :key="index" @click="plateInput(index)">
<view class="car-input-item"
:class="[curInput == index?'sel-item':'',(maxNum-1) == index?'last-item':'']" >
<view :class="curInput == index?'sel-item-line':''"></view>
<img :src="xnyImgBase64" class="new-item-img" v-if="(maxNum-1) == index"/>
{{item}}
</view>
</view>
</view>
<view class="car-number-container" v-if="showKeyPop1">
<view class="plate-close" @click="closeKeyboard"><text class="plate-close-btn">关闭</text></view>
<view class="plate-popup-list">
<view class="plate-popup-item province-item" v-for="(item,index) in keyProvince1" :key="index" @click="tapKeyboard(item)">{{item}}</view>
</view>
<view class="plate-popup-list">
<view class="plate-popup-item province-item" v-for="(item,index) in keyProvince2" :key="index" @click="tapKeyboard(item)">{{item}}</view>
</view>
<view class="plate-popup-list">
<view class="plate-popup-item province-item" v-for="(item,index) in keyProvince3" :key="index" @click="tapKeyboard(item)">{{item}}</view>
</view>
<view class="plate-popup-list">
<view class="plate-popup-item province-item" v-for="(item,index) in keyProvince4" :key="index" @click="tapKeyboard(item)">{{item}}</view>
<!-- 删除 -->
<view class="plate-popup-item province-item del" @click="onPlateDelTap">
<image :src="deleteImgBase64" />
</view>
</view>
</view>
<view class="car-number-container" v-if="showKeyPop2">
<view class="plate-close" @click="closeKeyboard"><text class="plate-close-btn">关闭</text></view>
<view class="plate-popup-list">
<view class="plate-popup-item" :class="lockInput.includes(item)?'lock-item':''"
v-for="(item,index) in keyEnInput1" :key="index" @click="tapKeyboard(item)">
{{item}}
</view>
</view>
<view class="plate-popup-list">
<view class="plate-popup-item" :class="lockInput.includes(item)?'lock-item':''"
v-for="(item,index) in keyEnInput2" :key="index" @click="tapKeyboard(item)">
{{item}}
</view>
</view>
<view class="plate-popup-list">
<view class="plate-popup-item" :class="lockInput.includes(item)?'lock-item':''"
v-for="(item,index) in keyEnInput3" :key="index" @click="tapKeyboard(item)">
{{item}}
</view>
</view>
<view class="plate-popup-list">
<view class="plate-popup-item" :class="lockInput.includes(item)?'lock-item':''"
v-for="(item,index) in keyEnInput4" :key="index" @click="tapKeyboard(item)">
{{item}}
</view>
<!-- 删除 -->
<view class="plate-popup-item del" @click="onPlateDelTap">
<image :src="deleteImgBase64" />
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'car-number-input',
emits: ['numberInputResult'],
props: {
defaultStr:{
type: String,
default: ''
},
plateNum: {
type: String,
default: ''
},
// maxNum: {
// type: Number,
// default: 8
// },
},
data() {
return {
inputList:[" "," "," "," "," "," "," "," "],
curInput:-1,
maxNum:8,
showKeyPop1:false,
showKeyPop2:false,
keyProvince1: ['京', '津', '晋', '冀', '蒙', '辽', '吉', '黑', '沪'],
keyProvince2: ['苏', '浙', '皖', '闽', '赣', '鲁', '豫', '鄂', '湘'],
keyProvince3: ['粤', '桂', '琼', '渝', '川', '贵', '云', '藏'],
keyProvince4: ['陕', '甘', '青', '宁', '新', 'W' ],
keyEnInput1: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"],
keyEnInput2: ["Q", "W", "E", "R", "T", "Y", "U", "P", "学", "军"],
keyEnInput3: ["A", "S", "D", "F", "G", "H", "J", "K", "L", "警"],
keyEnInput4: ["Z", "X", "C", "V", "B", "N", "M", "港", "澳"],
lockInput: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"],
xnyImgBase64:"data:image/png;base64,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PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjItMDktMTlUMTU6MDQ6NDQrMDg6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjItMDktMTlUMTU6MDQ6NDQrMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIyLTA5LTE5VDE1OjA0OjQ0KzA4OjAwIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmNjMmVkZmYwLTk0NjktNGJhNC1hODc2LWVkYmJlZjRhYjk0MyIgeG1wTU06RG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOmJkYTBhZTk3LWFmZWYtOWI0Ni1iOGFhLWZjOTMyMmM5OTk0NCIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjM1N2JlZGY2LTI5YWUtNGJmNS04YjQwLTVlMWQ5YjNlMmJmZiIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9IkRpc3BsYXkiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozNTdiZWRmNi0yOWFlLTRiZjUtOGI0MC01ZTFkOWIzZTJiZmYiIHN0RXZ0OndoZW49IjIwMjItMDktMTlUMTU6MDQ6NDQrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMS4wIChNYWNpbnRvc2gpIi8+IDxyZGY6bGkgc3RFdnQ6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",
deleteImgBase64:"data:image/png;base64,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"
}
},
watch: {
defaultStr(val) {
if(val != "" && val != null){
const valList = val.split("")
for (let i in valList) {
this.inputList[i] = valList[i]
}
}
},
curInput(val){
this.showOrHidePop(val)
this.keyEnInput2 = ["Q", "W", "E", "R", "T", "Y", "U", "O", "P", "军"]
switch(val){
case 1:
this.lockInput = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "学", "军", "警", "港", "澳"]
break
case 2:
this.lockInput = ["O", "学", "军", "警", "港", "澳"]
break
case 3:
this.lockInput = ["O", "学", "军", "警", "港", "澳"]
break
case 4:
this.lockInput = ["O", "学", "军", "警", "港", "澳"]
break
case 5:
this.lockInput = ["O", "学", "军", "警", "港", "澳"]
break
case 6:
this.lockInput = ["O"]
this.keyEnInput2 = ["Q", "W", "E", "R", "T", "Y", "U", "P", "学", "军"]
break
case 7:
this.lockInput = ["O", "学", "军", "警", "港", "澳"]
break
default:
this.lockInput = []
break
}
}
},
created() {
if(this.defaultStr != "" && this.defaultStr != null){
const valList = this.defaultStr.split("")
for (let i in valList) {
this.inputList[i] = valList[i]
}
}
},
methods: {
plateInput(e){
this.curInput = e
this.showOrHidePop(e)
},
showOrHidePop(val){
if(val == -1){
this.showKeyPop1 = false
this.showKeyPop2 = false
}else if(val == 0){
this.showKeyPop1 = true
this.showKeyPop2 = false
}else{
this.showKeyPop1 = false
this.showKeyPop2 = true
}
},
tapKeyboard(e){
if(this.lockInput.includes(e)){
return
}
this.inputList[this.curInput] = e
if(this.curInput < this.maxNum-2){
this.curInput++
}else{
this.curInput = -1
}
this.emitResult()
},
closeKeyboard(){
this.curInput = -1
},
onPlateDelTap(){
if(this.inputList[this.curInput] == " "){
this.curInput--
}
this.inputList[this.curInput] = " "
this.emitResult()
},
emitResult(){
const returnResult = this.inputList.join("")
this.$emit('numberInputResult', returnResult);
}
}
};
</script>
<style scoped lang="scss">
.car-input-container{
position: relative;
padding: 0 5px;
height: 44px;
.car-input-box{
display: inline-block;
width: 12.5%;
height: 44px;
vertical-align: middle;
.car-input-item{
position: relative;
border: 1px solid #E2E2E2;
border-radius: 10rpx;
height: 40px;
line-height: 40px;
width: 80%;
margin-left: 10%;
text-align: center;
font-size: 17px;
.sel-item-line{
position: absolute;
bottom: 3px;
left: 15%;
height: 2px;
background-color: #2979ff;
width: 70%;
}
.new-item-img{
position: absolute;
top: -6px;
left: 50%;
margin-left: -15px;
height: 13px;
width: 30px;
z-index: 9;
}
}
.sel-item{
color: #2979ff;
}
.last-item{
border: 1px solid #18bc37;
}
}
}
.car-number-container{
position: fixed;
z-index: 999;
bottom: 0;
left: 0;
width: 100%;
height: 254px;
background-color: #E3E2E7;
-webkit-box-shadow: 0 0 30upx rgba(0, 0, 0, 0.1);
box-shadow: 0 0 30upx rgba(0, 0, 0, 0.1);
overflow: hidden;
text-align: center;
.plate-close{
height: 40px;
line-height: 40px;
text-align: right;
background-color: #FFF;
.plate-close-btn{
font-size: 13.5px;
color: #555;
margin-right: 15px;
}
}
//键盘主体内容-单行
.plate-popup-list {
margin: 0 auto;
overflow: hidden;
display: inline-block;
display: table;
&:last-child {
margin-bottom: 2px;
}
}
//键盘主体内容-单个
.plate-popup-item {
float: left;
font-size: 16px;
width: 8vw;
margin: 0 1vw;
margin-top: 8px;
height: 40px;
line-height: 40px;
background: #FFFFFF;
border-radius: 5px;
color: #4A4A4A;
image {
width: 16px;
height: 16px;
margin: 12px auto;
}
}
.plate-popup-item:active{
background-color: #EAEAEA;
}
.province-item{
width: 8.8vw;
}
.lock-item{
color: #AAA;
}
}
</style>
使用方法
在父组件中引入并使用该车牌号选择组件:
1 | <template> |
组件结构
组件主要分为两部分:车牌号输入框和自定义键盘。
template 部分
1 | <template> |
script 部分
1 | <script> |
style 部分
1 | <style scoped lang="scss"> |
功能解析
1. 车牌格式与输入框
车牌号的输入格式为:
- 普通车牌:7位字符(1位省份简称 + 1位字母 + 5位字母或数字)
- 新能源车牌:8位字符(1位省份简称 + 1位字母 + 6位字母或数字,最后一位用绿色框标识)
在组件中,使用了一个长度为8的数组来存储车牌号各位的字符:
1 | inputList:[" "," "," "," "," "," "," "," "] |
并使用 v-for
指令遍历数组,创建对应数量的输入框:
1 | <view class="car-input-box" |
2. 自定义键盘设计
组件实现了两种不同的键盘:
- 省份简称键盘:用于输入车牌的第一位,包含全国各省市自治区的简称。
- 字母数字键盘:用于输入车牌的其他位置,包含字母、数字以及特殊标识(如”学”、”警”等)。
键盘布局采用了多行设计,使用者可以快速找到并点击所需的字符:
1 | <view class="plate-popup-list"> |
3. 输入规则与限制
车牌号的不同位置有不同的输入规则。例如:
- 第一位只能是省份简称
- 第二位通常只能是字母
- 其他位置可以是字母或数字
组件通过 watch
监听当前输入位置 curInput
的变化,动态设置当前位置可用和禁用的字符:
1 | watch: { |
禁用的字符在键盘上以灰色显示,并且不响应点击事件:
1 | <view class="plate-popup-item" :class="lockInput.includes(item)?'lock-item':''" |
4. 新能源车牌支持
新能源车牌比普通车牌多一位,且最后一位通常用绿色边框标识。组件通过条件渲染和特殊样式来实现这一特性:
1 | <view class="car-input-item" |
其中 last-item
类应用了绿色边框,而 new-item-img
则显示了新能源车标识。
5. 事件处理与交互
组件实现了多种交互方式:
- 点击输入框:激活对应位置的输入并弹出相应键盘
- 点击键盘字符:输入字符并自动跳转到下一位
- 点击删除按钮:删除当前位置的字符
- 点击关闭按钮:收起键盘
当输入完成或变更时,组件会通过事件向父组件传递当前的车牌号:
1 | emitResult(){ |
组件优化方向
- 支持自定义车牌长度:目前组件固定为8位,可以通过props动态设置长度以支持更多车牌类型。
- 增加输入验证:可以添加车牌格式的实时验证功能,提示用户输入是否符合规范。
- 改进键盘布局:可根据用户习惯优化键盘布局,提高输入效率。
- 增加动画效果:为键盘弹出/收起和输入框切换添加平滑过渡动画。
总结
通过本文,我们实现了一个功能完善的车牌号选择组件,支持普通车牌和新能源车牌的输入。该组件封装了复杂的交互逻辑和输入规则,为用户提供了便捷的车牌号输入体验。在实际项目中,可以根据具体需求对组件进行进一步定制和优化。
希望这个组件能够帮助到各位开发者,如有任何问题或建议,欢迎在评论区留言交流!
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果