帖子
帖子
用户
博客
课程

AVM框架 封装车牌号输入键盘组件

YonBuilder移动开发 2022-6-6 10:12 543人浏览 2人回复
原作者: wuliyuye 收藏 邀请
摘要

封装了车牌号输入键盘,支持燃油汽车、新能源车辆、教练车、挂车、警车5种模式。针对输入的车牌号进行了正则验证。 如有其他类型的车牌需要输入,可在此基础上进行添加即可,主要是控制号牌长度和一些固定的字。 组 ...

封装了车牌号输入键盘,支持燃油汽车、新能源车辆、教练车、挂车、警车5种模式。针对输入的车牌号进行了正则验证。
如有其他类型的车牌需要输入,可在此基础上进行添加即可,主要是控制号牌长度和一些固定的字。
组件引用
  1. import '../../components/car-num-keyboard.stml'
复制代码

组件使用
  1. <car-num-keyboard v-bind:mode={mode} v-if="isSetCarNum"></car-num-keyboard>
复制代码

组件文件car-num-keyboard.stml
  1. <template>
  2.         <view class={"keyboard-box-bg" + (transition?' keyboard-box-bg-transition':'')}>
  3.                 <view style="height:100%;"></view>
  4.                 <view class={"keyboard-box" + (transition?' keyboard-box-transition':'')}>
  5.                         <view class="header">
  6.                                 <text @click="cancelLicense">取消</text>
  7.                                 <text>{licenseType}</text>
  8.                                 <text @click="successLicense">完成</text>
  9.                         </view>
  10.                         <view class="license-number">
  11.                                 <view class="license-number-item" v-for="item in licenseNumber">
  12.                                         <text>{item}</text>
  13.                                 </view>
  14.                         </view>
  15.                         <view class="keyboard">
  16.                                 <view class="keyboard-item" v-for="item in provinces" data-value={item} @click="setNumber" v-show="!isProvince">
  17.                                         <text class="keyboard-item-title">{item}</text>
  18.                                 </view>
  19.                                 <view class="keyboard-item-key" v-for="item in licenseKey" data-value={item} @click="setNumberKey" v-show="isProvince">
  20.                                         <text class="keyboard-item-title">{item}</text>
  21.                                 </view>
  22.                                 <image class="keyboard-item-ico" src='../../image/key-back.png' mode="widthFix" @click="delLicenseNUmber"></image>
  23.                         </view>
  24.                 </view>
  25.                 <safe-area></safe-area>
  26.         </view>
  27. </template>
  28. <script>
  29.         export default {
  30.                 name: 'car-num-keyboard',
  31.                 installed(){
  32.                          if(this.props.mode=='new'){
  33.                                 this.data.licenseNumber=['','','','','','','',''];
  34.                                 this.data.licenseType='新能源汽车号牌';
  35.                                 this.data.numberLength = 8;
  36.                         }
  37.                         else if(this.props.mode=='trailer'){
  38.                                 this.data.licenseNumber=['','','','','','','挂'];
  39.                                 this.data.licenseType='挂车号牌';
  40.                                 this.data.numberLength = 6;
  41.                         }
  42.                         else if(this.props.mode=='instructional'){
  43.                                 this.data.licenseNumber=['','','','','','','学'];
  44.                                 this.data.licenseType='挂车号牌';
  45.                                 this.data.numberLength = 6;
  46.                         }
  47.                         else if(this.props.mode=='police'){
  48.                                 this.data.licenseNumber=['','','','','','','警'];
  49.                                 this.data.licenseType='警车号牌';
  50.                                 this.data.numberLength = 6;
  51.                         }
  52.                         else{
  53.                                 this.data.licenseNumber = ['', '', '', '', '', '', ''];
  54.                                 this.data.licenseType='燃油汽车号牌';
  55.                                 this.data.numberLength = 7;
  56.                         }     
  57.                         this.data.keyBoards = this.data.licenseKey;
  58.                         setTimeout(()=>{
  59.                                 this.data.transition = true;
  60.                         }, 50);
  61.                 },
  62.                 props:{
  63.                         mode:String
  64.                 },
  65.                 data() {
  66.                         return{
  67.                                 provinces: ['京', '津', '冀', '晋', '蒙', '辽', '吉', '黑', '沪', '苏', '浙', '皖', '闽', '赣', '鲁', '豫', '鄂', '湘', '粤', '桂', '琼', '渝', '川', '贵', '云', '藏', '陕', '甘', '青', '宁', '新'],         
  68.                                 licenseNumber: [],
  69.                                 licenseKey: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
  70.                                 keyBoards: [],
  71.                                 isProvince: false,
  72.                                 licenseNumberIndex: 0,
  73.                                 licenseType: '燃油汽车号牌',
  74.                                 mode:'',
  75.                                 numberLength:7,
  76.                                 transition: false
  77.                         }
  78.                 },
  79.                 methods: {
  80.                         setNumber(e) {
  81.                                 if (this.data.licenseNumberIndex == 0) {
  82.                                         this.data.licenseNumber[0] = e.dataset.value;
  83.                                         this.data.licenseNumberIndex += 1;
  84.                                         this.data.isProvince = true;
  85.                                 }
  86.                         },
  87.                         setNumberKey(e) {
  88.                                 if (this.data.licenseNumberIndex < this.data.numberLength) {
  89.                                         this.data.licenseNumber[this.data.licenseNumberIndex] = e.dataset.value;
  90.                                         this.data.licenseNumberIndex += 1;
  91.                                 }
  92.                         },
  93.                         delLicenseNUmber() {
  94.                                 this.data.licenseNumberIndex -= 1;
  95.                                 if (this.data.licenseNumberIndex == 0) {
  96.                                         this.data.isProvince = false;
  97.                                 }
  98.                                 this.data.licenseNumber[this.data.licenseNumberIndex] = '';
  99.                         },
  100.                         cancelLicense() {
  101.                                 this.fire('cancal','');
  102.                         },
  103.                         successLicense() {
  104.                                 let licenseNumber = this.data.licenseNumber.join('');
  105.                                 //校验车牌号
  106.                                 const carReg=/^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z](([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]))$/;
  107.                                 if(!carReg.test(licenseNumber)){
  108.                                 api.confirm({
  109.                                                 title: '提醒',
  110.                                                 msg: '您输入的车牌号可能无效,是否继续使用?',
  111.                                                 buttons: ['确定', '取消']
  112.                                         }, (ret, err) => {
  113.                                                 // var index = ret.buttonIndex;
  114.                                                 if(ret.buttonIndex==1){                                       
  115.                                                         this.fire('getNum',{carNum:licenseNumber,mode:this.props.mode});
  116.                                                 }
  117.                                         });
  118.                                 }
  119.                                 else{
  120.                                         this.fire('getNum',{carNum:licenseNumber,mode:this.props.mode});
  121.                                 }   
  122.                         }
  123.                 }
  124.         }
  125. </script>
  126. <style>
  127.         .keyboard-box-bg{
  128.                 position: absolute;
  129.                 width: 100%;
  130.                 height: 100%;
  131.                 background-color: rgba(0,0,0,0.1);
  132.                 transition-property: background-color;
  133.                 transition-duration: 0.3s;
  134.         }
  135.         .keyboard-box-bg-transition{
  136.                 background-color: rgba(0,0,0,0.4);
  137.         }
  138.         .keyboard-box{
  139.                 align-items: center;
  140.                 position: absolute;
  141.                 bottom: 0;
  142.                 width: 100%;
  143.                 background-color: white;
  144.                 box-sizing: border-box;
  145.                 transform: translateY(100%);
  146.                 transition-property: transform;
  147.                 transition-duration: 0.3s;
  148.         }
  149.         .keyboard-box-transition{
  150.                 transform: translateY(0);
  151.         }
  152.         .header {
  153.                 background-color: #dddddd;
  154.                 flex-flow: row nowrap;
  155.                 justify-content: space-between;
  156.                 align-items: center;
  157.                 padding: 8px 15px;
  158.                 width: 100%;
  159.         }
  160.         .license-number {
  161.                 flex-flow: row nowrap;
  162.                 justify-content: space-between;
  163.                 align-items: center;
  164.                 padding: 30px;
  165.                 background-color: #ffffff;
  166.                 width: 100%;
  167.         }
  168.         .license-number-item {
  169.                 width: 10%;
  170.                 justify-content: center;
  171.                 align-items: center;
  172.                 border: 0.5px solid #cccccc;
  173.                 border-radius: 5px;
  174.                 padding: 5px 0;
  175.                 min-height: 35px;
  176.         }
  177.         .keyboard {
  178.                 background-color: #ffffff;
  179.                 width: 100%;
  180.         }
  181.         .keyboard {
  182.                 flex-flow: row wrap;
  183.                 align-items: center;
  184.                 padding: 0 10px 10px 10px;
  185.         }
  186.         .keyboard-item {
  187.                 width: 12.5%;
  188.                 justify-content: center;
  189.                 align-items: center;
  190.         }
  191.         .keyboard-item-key {
  192.                 width: 10%;
  193.                 justify-content: center;
  194.                 align-items: center;
  195.         }
  196.         .keyboard-item-title {
  197.                 border: 0.5px solid #ccc;
  198.                 border-radius: 5px;
  199.                 padding: 5px 10px;
  200.                 margin: 10px 0;
  201.         }
  202.         .keyboard-item-ico {
  203.                 width: 30px;
  204.                 margin-left: 10px;
  205.         }
  206. </style>
复制代码

示例代码
  1. <template>
  2.         <view class="page">
  3.                 <safe-area></safe-area>                       
  4.                 <view class="car-box" data-mode="oil" @click="openCarNumKeyboard">
  5.                         <text class="car-label">燃油汽车号牌</text>
  6.                         <text class="car-num">{carNumber}</text>
  7.                 </view>
  8.                 <view class="car-box" data-mode="new" @click="openCarNumKeyboard">
  9.                         <text class="car-label">新能源汽车号牌</text>
  10.                         <text class="car-num">{carNumber1}</text>
  11.                 </view>
  12.                 <view class="car-box" data-mode="trailer" @click="openCarNumKeyboard">
  13.                         <text class="car-label">挂车号牌</text>
  14.                         <text class="car-num">{carNumber2}</text>
  15.                 </view>
  16.                 <view class="car-box" data-mode="instructional" @click="openCarNumKeyboard">
  17.                         <text class="car-label">教练车号牌</text>
  18.                         <text class="car-num">{carNumber3}</text>
  19.                 </view>
  20.                 <view class="car-box" data-mode="police" @click="openCarNumKeyboard">
  21.                         <text class="car-label">警车号牌</text>
  22.                         <text class="car-num">{carNumber4}</text>
  23.                 </view>
  24.                 <car-num-keyboard v-bind:mode={mode} v-if="isSetCarNum"></car-num-keyboard>
  25.         </view>
  26. </template>
  27. <script>
  28.         import '../../components/car-num-keyboard.stml'
  29.         export default {
  30.                 name: 'license-number',
  31.                 apiready(){
  32.                        
  33.                 },
  34.                 data() {
  35.                         return{
  36.                                 carNumber:'',
  37.                                 carNumber1:'',
  38.                                 carNumber2:'',
  39.                                 carNumber3:'',
  40.                                 carNumber4:'',
  41.                                 isSetCarNum:false,
  42.                                 mode:''
  43.                         }
  44.                 },
  45.                 methods: {
  46.                         openCarNumKeyboard(e){                       
  47.                                 this.data.mode = e.dataset.mode;
  48.                                 this.data.isSetCarNum = true;//传递动态值 先传值初始化元素
  49.                         },
  50.                         claseKeyboard(e){
  51.                                 this.data.isSetCarNum = false;
  52.                                 this.data.mode = '';
  53.                         },
  54.                         getCarNum(e){
  55.                                 this.data.isSetCarNum = false;
  56.                                 if(e.detail.mode=='new'){
  57.                                         this.data.carNumber1=e.detail.carNum;
  58.                                 }
  59.                                 else if(e.detail.mode=='trailer'){
  60.                                         this.data.carNumber2=e.detail.carNum;
  61.                                 }
  62.                                 else if(e.detail.mode=='instructional'){
  63.                                         this.data.carNumber3=e.detail.carNum;
  64.                                 }
  65.                                 else if(e.detail.mode=='police'){
  66.                                         this.data.carNumber4=e.detail.carNum;
  67.                                 }
  68.                                 else{
  69.                                         this.data.carNumber = e.detail.carNum;
  70.                                 }
  71.                         }
  72.                 }
  73.         }
  74. </script>
  75. <style>
  76.         .page {
  77.                 height: 100%;
  78.                 background-color: #ffffff;
  79.         }
  80.         .car-box{
  81.                 margin: 10px;
  82.                 padding-bottom: 5px;
  83.                 border-bottom: 0.5px solid #cccccc;
  84.         }
  85.         .car-label{
  86.                 font-size: 15px;
  87.                 color: #666666;
  88.         }
  89.         .car-num{
  90.                 font-size: 20px;
  91.                 min-height: 20px;
  92.         }

  93. </style>
复制代码

示例演示
微信图片_20220530104436.jpg微信图片_20220530104431.jpg

注意点:
在调用键盘的时候,是通过v-if 进行键盘的显示和隐藏,v-if  false的情况会销毁元素,所以需要传递的动态值,必须要在元素重新创建之前进行赋值操作。如下图所示,先后顺序很重要。
eb3437cd54b566d4e561c23f787e349.png

评论
543人参与,2条评论

精彩评论
  • 技术呆 新手上路 -9436Y币
    发表于 2022-5-30 11:00
    赞赞赞赞赞赞
  • 技术咨询-F 版主 6Y币
    发表于 2022-5-30 13:55
    参加组件大赛了吗? css 样式加上一个自己的独特前缀,这样不容易和其他样式冲突。

查看全部评论>>