用vue写了个移动端车牌输入键盘

本文分享了作者作为Vue初学者制作的一个车牌号码输入组件的全过程。从界面设计到交互逻辑,作者详细记录了实现过程中的难点及解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

话不多说,先看图

 

初学vue,断断续续花了一天半才写出来.... 写样式真的很麻烦 下面上代码

html

 1 <template>
 2     <section class="pkey-contain">
 3         <section class="pkey-win">
 4             <header class="pkey-header">车牌号码</header>
 5             <div class="pkey-win-body">
 6                 <div class="pkey-ipt pkey-foucs">{{plate}}</div>
 7                 <div class="pkey-tips">{{tips}}</div>
 8             </div>
 9         </section>
10         <section class="pkey-keyboard">
11             <header class="pkey-header2">
12                 <label class="pkey-chacelbtn" @click="closewin">取消</label><label class="pkey-okbtn" @click="checkplate">完成</label>
13             </header>
14             <section class="pkey-keyscontain">
15                 <ul>
16                     <li v-show="txtboardshow" v-for="(item,index) in cartxt">
17                         <span v-show="index==cartxt.length-1" @click="txtboardshow=false,numboardshow=true">ABC</span>
18                         <label v-for="(items,indexi) in item" @click="txtclick(items,indexi,item.length)">{{items}}</label>
19                         <span v-show="index==cartxt.length-1" @click="plate=plate.substr(0, plate.length-1)">&nbsp;</span>
20                     </li>
21                     <li v-show="numboardshow" v-for="(item,index) in numtxt">
22                         <span v-show="index==cartxt.length-1" @click="txtboardshow=true,numboardshow=false"></span>
23                         <label v-for="(items,indexi) in item" @click="numclick(items,indexi,item.length)">{{items}}</label>
24                         <span v-show="index==cartxt.length-1" @click="plate=plate.substr(0, plate.length-1)">&nbsp;</span>
25                     </li>
26                 </ul>
27             </section>
28             <transition name="fade">
29                 <section class="showkey" v-show="keyshow" :keyshow="keyshow" :style="{marginLeft:mleft+'px'}">{{keyb}}</section>
30             </transition>
31         </section>
32     </section>
33 </template>

script

  1 <script>
  2 export default{
  3     data(){
  4         return{
  5             plate:'',
  6             keyb:'',
  7             txtboardshow:true,
  8             numboardshow:false,
  9             keyshow:false,
 10             mleft:0,
 11             tips:'',
 12             cartxt:[
 13                 ['京','津','渝','沪','冀','晋','辽','吉','黑','苏'],
 14                 ['浙','皖','闽','赣','鲁','豫','鄂','湘','粤','琼'],
 15                 ['川','贵','云','陕','甘','青','蒙','桂','宁','新'],
 16                 ['藏','使','领','警','学','港','澳']
 17             ],
 18             numtxt:[
 19                 ['1','2','3','4','5','6','7','8','9','0'],
 20                 ['Q','W','E','R','T','Y','U','I','O','P'],
 21                 ['A','S','D','F','G','H','J','K','L'],
 22                 ['Z','X','C','V','B','N','M']
 23             ],
 24         }
 25     },
 26     methods: {
 27         txtclick : function(txt,indexi,size){
 28             if(this.plate.length>10){
 29                 return
 30             }
 31             this.txtboardshow = false;
 32             this.numboardshow = true;
 33             this.plate+=txt;
 34             this.keyb = txt;
 35             this.composition(indexi,size);            
 36         },
 37         numclick : function(num,indexi,size){
 38             if(this.plate.length>10){
 39                 return
 40             }
 41             this.plate+=num;
 42             this.keyb = num;
 43             this.composition(indexi,size);
 44             
 45         },
 46         composition : function(indexi,length){
 47             //闪烁位置设置
 48             let winwidth = document.documentElement.clientWidth;
 49             let keyW = winwidth * 65 / 750;
 50             let kkongW = winwidth * 9 / 750;
 51             let showW = winwidth * 120 / 750;
 52             let size = length;
 53             let isEven = (size%2==0) ? true : false;
 54             if(indexi<size/2){ // 左边
 55                 let mleft = 0;
 56                 if(isEven){ // 偶数
 57                     let n = size/2-(indexi+1) + 0.5;
 58                     mleft = n*(keyW + kkongW) + showW/2;
 59                 }
 60                 else{ // 奇数
 61                     let n = (size/2+0.5)-(indexi+1);
 62                     mleft = n*(keyW + kkongW) + showW/2;
 63                 }                
 64                 mleft = (mleft > winwidth/2) ? winwidth/2 : mleft;
 65                 this.mleft = -mleft;
 66             }else{ // 右边
 67                 let mright = 0;
 68                 if(isEven){
 69                     let n = (indexi+1) - size/2 -0.5;
 70                     mright = n*(keyW + kkongW) - showW/2;
 71                 }else{
 72                     let n = (indexi+1) - (size/2+0.5);
 73                     mright = n*(keyW + kkongW) - showW/2;
 74                 }                
 75                 mright = (mright > (winwidth/2-showW)) ? (winwidth/2-showW) : mright;
 76                 this.mleft = mright;
 77             }
 78             //闪烁
 79             this.keyshow = true;
 80             let self = this;
 81             setTimeout(function(){
 82                 self.keyshow = false;
 83             },250);
 84             
 85         },
 86         checkplate : function(){
 87             if(this.plate==''){
 88                 this.tips = '请输入车牌号码'
 89                 return;
 90             }            
 91             if(!(/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[警京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{0,1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}[A-Z0-9]{0,1}[A-Z0-9]{0,1}$/.test(this.plate))){
 92                 //不是车牌
 93                 this.tips = '车牌号格式不正确'        
 94                 return;
 95             }
 96             this.tips = '';            
 97             this.$emit('transferplate',this.plate);
 98             this.plate = '';
 99             this.txtboardshow = true;
100             this.numboardshow = false;
101         },
102         closewin : function(){
103             this.tips = '';    
104             this.$emit('transferclose',false);
105             this.plate='';
106             this.txtboardshow = true;
107             this.numboardshow = false;
108         }
109     }
110 }    
111 </script>

 

样式也是第一次用大神推荐的vw做适配,真的蛮方便(之前一直用flexible.js)但是有个问题:怎么能设置固定宽度,因为用电脑打开的话整个页面很大...看起来很夸张,而且因为它是根据视口做的适配吧 max-width也不好用,求各位朋友教教我.

 

转载于:https://www.cnblogs.com/locim/p/8760901.html

### Vue3 移动端车牌输入法实现 为了实现在 Vue3 项目中针对移动端车牌输入法功能,可以采用自定义组件的方式。通过创建一个专门用于车牌号输入的表单控件来满足特定需求。 #### 创建 LicensePlateInput 组件 ```vue <template> <div class="license-plate-input"> <!-- 车牌前缀选择 --> <select v-model="provinceCode" @change="onProvinceChange()"> <option value="">请选择省份</option> <option v-for="(item, index) in provinces" :key="index">{{ item }}</option> </select> <!-- 字符串形式展示已选字符 --> <input type="text" ref="inputRef" maxlength="7" pattern="[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵青藏川宁琼港澳使领]{1}[A-Z0-9]{6}" placeholder="请输入车牌号码" v-model.trim="currentValue" readonly /> <!-- 显示键盘按钮 --> <ul class="keyboard"> <li v-for="(char, idx) of chars" :key="idx" @click="appendChar(char)"> {{ char }} </li> </ul> </div> </template> <script setup lang="ts"> import { ref } from 'vue'; const props = defineProps({ modelValue: { type: String, default: '' } }); // 定义 emit 函数以便更新父级绑定的数据 const emit = defineEmits(['update:modelValue']); let currentValue = ref(props.modelValue); let provinceCode = ref(''); function onProvinceChange() {} function appendChar(character:string): void { const maxLen = 7; if (currentValue.value.length >= maxLen) return; // 更新当前值并通知外部变化 currentValue.value += character; emit('update:modelValue', `${provinceCode.value}${currentValue.value}`); } </script> <style scoped> /* 添加样式 */ .keyboard li { display: inline-block; padding: .5em; } .license-plate-input input[type=text]{ width: calc(100% - 2rem); /* 自适应宽度减去左右内边距 */ text-align: center; /* 居中文本 */ font-size: large; /* 增大字体便于查看 */ } </style> ``` 此代码片段展示了如何构建一个简单的车牌输入框及其对应的虚拟键盘[^1]。注意这里只实现了基本框架,在实际应用时还需要考虑更多细节比如: - 对不同地区编码的支持; - 输入验证逻辑; - 用户体验优化如点击屏幕自动弹出软键盘等特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值