网上一搜一大堆类似但大多都相对简单,适用的场景并不多。多数也不支持赋值 不支持单个删除更改
我就借鉴了以下文章的思路,为了达到自己想要的效果做了相对应的更改。
借鉴文章链接:> https://blog.csdn.net/qq706352062/article/details/105554453?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159652341219195188354739%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159652341219195188354739&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v3~pc_rank_v3-12-105554453.pc_ecpm_v3_pc_rank_v3&utm_term=%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E8%BD%A6%E7%89%8C%E8%BE%93%E5%85%A5%E9%94%AE%E7%9B%98&spm=1018.2118.3001.4187
效果图如下:
直接上代码!
WXML代码:
点击查看代码
<!-- 车牌号码输入框 -->
<view wx:for="{{carNum}}" wx:key="index" class="text-center inline-block" bind:tap='openKeyboard'><!-- 点 --><text wx:if="{{ index === 2 }}" class="inline-block ml-5 mr-5 fs-40">.</text><!-- 普通车牌 --><input wx:if="{{ index !== 7 }}" model:value="{{ item.value }}" data-index="{{index}}" class="com-carNumber-item {{ item.focus ? 'com-focus' : ''}}" /><!-- 新能源车牌 --><input wx:else model:value="{{!showNewPower ? '+' : item.value }}" data-index="{{index}}" class="com-carNumber-item {{showNewPower ? item.focus ? 'com-focus' : '': 'com-carNumber-item-newpower'}}" />
</view><!-- 虚拟键盘 -->
<view class="com-keyboard" hidden='{{!KeyboardState}}'><view class="com-keyboardConfirm flex-center"><text class="com-vehicleTip bold flex-center">请输入车牌号</text><view class="com-separator"></view><view class="com-keyboardConfirm_btn bold" bindtap='confirmKeyboard'>完成</view></view><!-- 省份简写键盘 --><view class="com-keyboard-item" hidden="{{ focusIndex !== 0 }}"><view wx:for="{{provinces}}" wx:key="index" class="com-keyboard-line"><view wx:for="{{item}}" wx:key="index" wx:for-item="char" data-val="{{char}}" class="com-keyboard-btn" bindtap='bindChoose'>{{char}}</view></view></view><!-- 车牌号码选择键盘 --><view class="com-keyboard-item com-carNumber" hidden="{{focusIndex === 0}}"><!-- 数字键盘 --><view wx:for="{{numbers}}" wx:key="index" class="com-keyboard-line"><view wx:for="{{item}}" wx:key="index" wx:for-item="char" data-val="{{char}}" class="{{ focusIndex !== 1 ? 'com-keyboard-btn' : 'com-keyboard-disabled-btn' }}" bindtap="{{ focusIndex !== 1 ? 'bindChoose' : '' }}">{{char}}</view></view><!-- 字母键盘 --><view wx:for="{{letters}}" wx:key="index" class="com-keyboard-line"><view wx:for="{{item}}" wx:key="index" wx:for-item="char" data-val="{{char}}" class="{{ focusIndex !== 6 && (char === '挂' || char === '港' || char === '澳' || char === '学') ? 'com-keyboard-disabled-btn' : 'com-keyboard-btn'}}" bindtap="bindChoose">{{char}}</view></view><view class="com-keyboard-del" bindtap='bindDelChoose'><text class="fs-40">删除</text></view></view>
</view>
JS代码:
点击查看代码
import { isEmpty, validate } from '../../utils/util';
const icon = 'none', duration = 3000const component = {properties: {vehicleNo: { type: String, value: undefined } // 车牌号},data: {provinces: [ // 省份键盘['京', '沪', '粤', '津', '冀', '晋', '蒙', '辽', '吉', '黑'],['苏', '浙', '皖', '闽', '赣', '鲁', '豫', '鄂', '湘'],['桂', '琼', '渝', '川', '贵', '云', '藏'],['陕', '甘', '青', '宁', '新']],numbers: [ // 数字键盘['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']],letters: [ // 字母键盘['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K'],['L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V'],['W', 'X', 'Y', 'Z', '挂', '港', '澳', '学']],specialChar: ['挂', '港', '澳', '学'], // 特殊字符carNum: Array(8).fill({ value: undefined, focus: false }),focusIndex: 0, // 输入库焦点索引showNewPower: false, // 是否新能源车牌KeyboardState: false // 是否弹出虚拟键盘},attached() {const v = thisconst vehcles = v.data.vehicleNo.split('')const carNum = v.data.carNumvehcles.forEach((m, i) => { carNum[i].value = m })v.setData({ carNum })},/*** 组件的方法列表*/methods: {// 车牌输入框点击展开车牌键盘openKeyboard(e) {const v = thisconst focusIndex = e.target.dataset.indexlet carNum = v.data.carNumlet showNewPower = v.data.showNewPower// 添加新能源尾数if (focusIndex === 7) {if (isEmpty(v.data.carNum[6].value)) return wx.showToast({ title: '为新能源车牌时,前几位车牌号不能为空', icon, duration })if (v.data.specialChar.includes(v.data.carNum[6].value)) return wx.showToast({ title: `为新能源车牌时,第6位车牌号不能为'${v.data.carNum[6].value}'`, icon, duration })showNewPower = truev.setData({ showNewPower, KeyboardState: true })}// 当前点击获得焦点,其余失去焦点carNum[focusIndex].focus = truecarNum = carNum.map((item, index) => {return { ...item, focus: index === focusIndex ? item.focus : false }})// 点击索引不为新能源时if (focusIndex !== 7) showNewPower = falsev.setData({ KeyboardState: true, focusIndex, carNum, showNewPower })},// 键盘选中点击设置bindChoose(e) {const v = thisconst val = e.target.dataset.valconst carNum = v.data.carNumlet focusIndex = v.data.focusIndexif (focusIndex !== 6 && v.data.specialChar.includes(val)) return// 当前选中车牌无值时更新为输入值if (isEmpty(carNum[focusIndex].value)) {carNum[focusIndex].value = valcarNum[focusIndex].focus = falseconst validate = v.data.showNewPower ? 7 : 6// 上一位车牌取消聚焦if (focusIndex < validate) focusIndex++carNum[focusIndex].focus = truev.setData({ carNum, focusIndex })}},// 删除bindDelChoose() {const v = thisconst carNum = v.data.carNumlet focusIndex = v.data.focusIndexlet showNewPower = v.data.showNewPower// 如果删除第6位后继续删除 则focusIndex后退一位并删除第5位车牌 依此类推 // 当删除至省份位车牌时,界面会控制取消删除按钮if (isEmpty(carNum[focusIndex].value)) {// 如果当前索引是新能源车牌 if (focusIndex == 7) showNewPower = falsefocusIndex--carNum[focusIndex].value = undefinedcarNum[focusIndex].focus = true// 后一位车牌取消聚焦carNum[focusIndex + 1].focus = false}else {carNum[v.data.focusIndex].value = undefinedcarNum[v.data.focusIndex].focus = true}v.setData({ carNum, focusIndex, showNewPower })},// 关闭虚拟键盘confirmKeyboard() {const v = thisconst vheicleNo = v.data.carNum.map(m => m.value).join('');if (!validate.vehicle(vheicleNo)) return wx.showToast({ title: '请输入正确的车牌', icon, duration })v.setData({ KeyboardState: false })v.triggerEvent('confirm', { vheicleNo })}}
}Component(component);
WXSS代码:
点击查看代码
/* 车牌号码 */
.com-carNumber-item {width: 55rpx;height: 60rpx;font-size: 18px;border: 2rpx solid #CCCCCC;border-radius: 8rpx;display: inline-block;line-height: 30px;margin: 0 2rpx;vertical-align: middle;caret-color: transparent;
}.com-focus {border: 4rpx solid #A8BFF3;
}/* 新能源 */
.com-carNumber-item-newpower {border: 2rpx dashed #19e622;background-color: #e1fde2;color: #19e622;font-size: 25px;line-height: 45rpx;
}/* 虚拟键盘 */
.com-keyboard {height: auto;background: #d1d5d9;position: fixed;bottom: 0;width: 100%;left: 0;padding-bottom: 30rpx;
}.com-keyboard-item {padding: 10rpx 0 5rpx 0;position: relative;display: block;
}.com-vehicleTip {flex: 1;color: rgba(150, 179, 253, 1);
}.com-separator {width: 1px;height: 50%;background-color: #ccc;margin: 0 10px;
}.com-keyboardConfirm {height: 70rpx;background-color: #f7f7f7;
}.com-keyboardConfirm_btn {float: right;line-height: 70rpx;font-size: 15px;margin-right: 30rpx;color: #FFA500;
}.com-keyboard-line {margin: 0 auto;text-align: center;
}.com-carNumber .com-keyboard-line {text-align: left;margin-left: 5rpx;
}.com-keyboard-btn {font-size: 18px;color: #333333;background: #fff;display: inline-block;padding: 18rpx 0;width: 63rpx;text-align: center;box-shadow: 0 2rpx 0 0 #999999;border-radius: 10rpx;margin: 5rpx 6rpx;
}.com-keyboard-disabled-btn {font-size: 18px;color: #333333;background: #cacaca;display: inline-block;padding: 18rpx 0;width: 63rpx;text-align: center;box-shadow: 0 2rpx 0 0 #999999;border-radius: 10rpx;margin: 5rpx 6rpx;
}.com-keyboard-del {color: black;background: #A7B0BC;display: inline-block;padding: 10rpx 25rpx;box-shadow: 0 2rpx 0 0 #999999;border-radius: 10rpx;margin: 5rpx;position: absolute;bottom: 10rpx;right: 12rpx;
}
公用样式代码(app.wxss):
点击查看代码
.text-center {text-align: center;
}.inline-block {display: inline-block;
}.ml-5 {margin-left: 5rpx;
}.mr-5 {margin-right: 5;
}.fs-40 {font-size: 40rpx;
}.bold {font-weight: bold;
}.flex-center {display: flex;align-items: center;justify-content: center;
}
公用JS代码:
点击查看代码
/*** 是否都是空数据(类型:字符串,数值,对象,数组,布尔)*/
const isEmpty = (...values) => {const isEmptyFunc = (val) => {switch (typeof val) {case 'string':case 'number': return !val // 数值0为空case 'object':// 数组if (Array.isArray(val)) return val.length === 0// null/对象return val === null || Object.keys(val).length === 0case 'boolean': return false // 布尔类型即非空// undefined / functiondefault: return true}}let result = truevalues.forEach(m => { result = result && isEmptyFunc(m) })return result
}/*** 验证*/
const validate = {/** 是车牌号 */vehicle(value) {let result = falseif (value && [7, 8].includes(value.length)) {const express = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4,5}[A-Z0-9挂学警港澳]{1}$/result = express.test(value)}return result}
}
上面gif生成是用 Windows 系统 Win+Shift+S 将操作截图成视频,再去这个网站 https://www.aconvert.com/cn/video/mp4-to-gif/ 将视频转成GIF
预览的时候把图片下载下来