小程序--自定义键盘车牌号

没啥特别的技术,就是记录一下自己开发时遇到的问题和解决方案,以后自己查看着方便

简介

自定义的车牌号键盘

效果

要实现一个方便输入车牌号的键盘和输入框,支持新能源车牌。

最开始的想法是用多个小程序的input输入框实现,但是发现了一个很不爽的体验,每个的输入框聚焦都会引发手机键盘的弹出,emmmm,这可不是我要的效果。

最终的实现方案就是 没用到一个input输入框,全部使用的div实现输入框效果。将键盘选中的内容存到一个数组里,输入框里展示对应数组的文字。

我把它写成一个component,方便多页面使用

wxml文件

 <view class="modal-box">
        <view class="modal-wrapper">
            <view class="modal-title">
                <view class="titleWrapper"><text class="title-text">请录入车牌号text>view>
                <view class="iconWrapper"><image class="close-icon" src="../images/close.png" bindtap="onCancel" />view>
            view>
            
            <view class="modal-content">
                <view class="modal-input">
                    <block wx:for="{{8}}" wx:key="index">
                        <view   data-index="{{index}}"  class="input {{selectInputIndex===index?'activeInput':''}}"  bindtap='inputCarNum'>
                            <text>{{carNumArr[index] || ''}}text>
                        view>
                    block>
                    <view class="line">view>
                view>
                
            view>
            <view class="model-btn-group">
                <button bindtap="onOk" class="btn confirm" disabled="{{btnDisabled}}">确认button>
            view>
        view>
        
        <view class='keyboard' >
          
          <view class="provinces" hidden='{{hiddenPro}}'>
            <view class="pro-li fl" wx:for="{{provinceArr}}" wx:key="index" catchtap='proTap' data-province="{{item}}">{{item}}view>
          view>
          
          <view class="keyNums" hidden='{{hiddenStr}}'>
            <view  wx:if="{{selectInputIndex===1}}" class="row numRow">
              <view  class="pro-li  disabled"  wx:for="{{numArr}}"  wx:key="index" data-str="{{item}}">{{item}}view>
            view>
           <view wx:else class="row numRow">
               <view  class="pro-li " wx:for="{{numArr}}"  wx:key="index" catchtap='strTap' data-str="{{item}}">{{item}}view>
            view>
           <view class="strOne row">
              <view  class="pro-li " wx:for="{{strArrOne}}" wx:key="index" catchtap='strTap' data-str="{{item}}">{{item}}view>
            view>
           <view class="strTwo row">
              <view  class="pro-li " wx:for="{{strArrTwo}}"wx:key="index" catchtap='strTap' data-str="{{item}}">{{item}}view>
           view>
           <view class="strThree row">
              <view class="pro-li " wx:for="{{strArrThree}}" wx:key="index" catchtap='strTap' data-str="{{item}}">{{item}}view>
              <view class='kb-icon pro-li' catchtap='backSpace'>
                <image class='delete-icon' src="../images/delete.png" />
              view>
           view>
          view>
        view>
       <view class="modal-cover">view>   
    view>


复制代码

js代码

const INPUT_NUM = 8;//车牌号输入框个数
const EmptyArray = new Array(INPUT_NUM).fill('');//['','','','','','','','']

// 车牌输入框的下标
const INPUT_INDEX = {
  FIRST: 0,
  SECOND: 1
};

Component({
  data: {
    // 键
    provinceArr: ['京', '沪', '津', '苏', '粤', '冀', '晋', '蒙', '辽', '吉', '黑', '浙', '皖', '闽', '赣', '鲁', '豫', '鄂', '湘', 
      '桂', '琼', '渝', '川', '贵', '云', '藏', '陕', '甘', '青', '宁', '新', '港', '澳', '台'],
    strArrOne: ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'P'],
    strArrTwo: ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],
    strArrThree: ['Z', 'X', 'C', 'V', 'B', 'N', 'M'],
    numArr: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
    hiddenPro: false, // 隐藏省份键盘
    hiddenStr: true, // 隐藏数字字母键盘
    carNumArr: EmptyArray,
    selectInputIndex: 0,
    btnDisabled: true
  },
  methods: {
    proTap(e) { //点击省份
      let province = e.currentTarget.dataset.province;
      const { carNumArr, selectInputIndex } = this.data;
      this.setData({
        hiddenPro: true,
        hiddenStr: false
      });
      carNumArr[selectInputIndex] = province;
      // 选择车牌号时触发
      this.setData({
        carNumArr,
        // 选中一个后,下一个输入框聚焦
        selectInputIndex: selectInputIndex !== carNumArr.length - 1 ? selectInputIndex + 1 : selectInputIndex,
        btnDisabled: this.btnDisabled()
      });
    },
    strTap(e) { //点击字母数字
      const str = e.currentTarget.dataset.str;
      const { carNumArr, selectInputIndex } = this.data;
      carNumArr[selectInputIndex] = str;
      this.setData({
        carNumArr,
        // 选中一个后,下一个输入框聚焦
        selectInputIndex: selectInputIndex !== carNumArr.length - 1 ? selectInputIndex + 1 : selectInputIndex,
        btnDisabled: this.btnDisabled()
      });
    },
    inputCarNum(e) {
      const { index } = e.currentTarget.dataset;
      this.setData({
        showCarKeyboard: true,
        selectInputIndex: index
      });
      if (index === INPUT_INDEX.FIRST) {
        // 第一个输入框展示省份键盘,第二个展示字母数字输入框(数字不可点),以后就是数字字母输入框(都可点)
        this.setData({
          hiddenPro: false,
          hiddenStr: true
        });
      } else if (index === INPUT_INDEX.SECOND) {
        this.setData({
          hiddenPro: true,
          hiddenStr: false
        });
      } else {
        this.setData({
          hiddenPro: true,
          hiddenStr: false
        });
      }
    },
    backSpace() { //删除
      const { carNumArr, selectInputIndex } = this.data;
      carNumArr[selectInputIndex] = '';
      this.setData({
        carNumArr,
        selectInputIndex: selectInputIndex !== INPUT_INDEX.FIRST ? selectInputIndex - 1 : selectInputIndex,
        btnDisabled: this.btnDisabled()
      }, () => {
        if (this.data.selectInputIndex === INPUT_INDEX.FIRST) { //这里必须要用this.data.selectInputIndex,用最新的
          this.setData({
            hiddenPro: false,
            hiddenStr: true
          });
        }
      });
    },
    // 只有输入内容的车牌号位数合法时,展示确认按钮
    btnDisabled() {
      const { carNumArr } = this.data;
      const disabled = carNumArr.some((item, index) => {
        if (index !== carNumArr.length - 1) {
          return !item;
        }
        return false;
      });
      return disabled;
    },
    onCancel() {
      this.setData({ carNumArr: EmptyArray });
      this.triggerEvent('onCancel');
    },
    onOk() {
      const carNum = this.data.carNumArr.join('');
      this.triggerEvent('onOk', carNum);
    }
  },
});
复制代码

wxss文件

/* 键盘 */
.keyboard {
	width: 100%;
	position: fixed;
	bottom: 0;
	left:0;
	z-index: 1000;
	background-color: rgba(210, 213, 219, 90);
}

.fl {
	float: left
}

.carnum {
	text-align: center;
	height: 88rpx
}

.tel {
	border-bottom: 2rpx solid #ddd;
	height: 100rpx;
	line-height: 100rpx;
}

.provinces {
	overflow: hidden;
	padding-top: 20rpx;
}

.pro-li {
	font-size: 32rpx;
	color: #353535;
	height: 76rpx;
	width: 62rpx;
	line-height: 76rpx;
	text-align: center;
	margin-left: 12rpx;
	margin-bottom: 20rpx;
	background-color: #fff;
	box-shadow: 0px 1rpx 2rpx 0 #979797;
	border-radius: 5px;
	flex: 1
}

.keyNums .disabled {
	background-color: #F7F7F7;
	color: #CCC
}

.keyNums {
	overflow: hidden;
	padding-top: 20rpx;
	display: flex;
	flex-direction: column;
}

.keyNums .row {
	display: flex;
}

.keyNums .numRow {
	padding: 0 10rpx;
}

.keyNums .strOne {
	padding: 0 10rpx;
}

.keyNums .strOne .strOneItem {
	flex: 1
}

.keyNums .strTwo {
	padding: 0 40rpx;
}

.keyNums .strOne .strTwoItem {
	flex: 1
}

.keyNums .strThree {
	padding-left: 116rpx;
	padding-right: 10rpx;
}

.keyNums .strOne .strThreeItem {
	flex: 1
}

.keyNums .strOne .strThreeItem:nth-child(7) {
	margin-left: 100px
}

.keyNums .pro-li:nth-child(16) {
	color: red
}

.keyNums .strThree .kb-del {
	margin-left: 12rpx
}

.keyNums .strThree .kb-icon {
	flex: 1.5;
	background: #ABB3BD;
	margin-left: 40rpx;
}

/* modal样式 */

.modal-box {
	width: 100%;
	position: absolute;
	top: 0;
	bottom: 0;
	display: flex;
	align-items: center;
	justify-content: center;
}

.modal-wrapper {
	margin: 30% 30rpx;
	height: 380rpx;
	padding: 30rpx;
	background-color: #fff;
	border-radius: 10rpx;
	z-index: 300;
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	display: flex;
	flex-direction: column;
	align-content: space-between;
	justify-content: space-between;
	overflow: hidden;
	text-align: left;
}

.modal-wrapper .model-btn-group {
	display: flex;
	box-sizing: border-box;
	font-size: 32rpx;
}

.model-btn-group view {
	width: 50%;
	text-align: center;
	box-sizing: border-box;
}

.model-btn-group .btn {
	flex: 1;
	font-size: 18px
}

.model-btn-group .cancel {
	color: #999;
}

.model-btn-group .confirm {
	color: #fff;
	background-color: #ff5000;
}

.model-btn-group .confirm.active {
	opacity: 1;
}

.modal-cover {
	width: 100%;
	background-color: #242424;
	opacity: 0.5;
	z-index: 299;
	position: fixed;
	top: 0;
	left: 0;
	bottom: 0;
	right: 0;
	margin: auto;
	overflow: hidden;
}

.modal-input {
	display: flex;
}

.modal-input .input {
	border: 1px solid #979797;
	margin-right:6rpx;
	border-radius: 3px;
	flex: 1;
	text-align: center;
	padding: 8px;
	height: 22px;
}

.modal-input .input:nth-child(1) {
	border-right-width: 0;
	margin-right: 0;
	position: relative;
	border-bottom-right-radius: 0;
	border-top-right-radius: 0;
}

.modal-input .input:nth-child(1)::after {
	content: "";
	position: absolute;
	right: -1px;
	width: 1px;
	height: 20px;
	background-color: #979797;
	z-index: -10
}


.modal-input .input:nth-child(2) {
	position: relative;
	border-left-width: 0;
	margin-right:20rpx;
	border-bottom-left-radius: 0;
	border-top-left-radius: 0;
}

.modal-input .input:nth-child(2)::after {
	content: "";
	position: absolute;
	right:-16rpx;
	top: 45%;
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background-color: #979797
}

.modal-input .input:nth-child(8) {
	border: 1px dashed #979797;
}

.modal-input .activeInput {
	border-radius: 3px !important;
	border: 1px solid #FF5000 !important
}

.modal-input .text {
	text-align: right;
	color: #c5c5c5;
	font-size: 28rpx;
}

.modal-placeholder-class {
	color: #c5c5c5;
}

.modal-title {
	display: flex;
	font-size: 20px;
	color: #333333
}

.titleWrapper {
	flex: 1;
}

.title-text {
	font-size: 18px;
	font-weight: bold;
}

.iconWrapper {
	flex: 1;
	text-align: right;
}

.close-icon {
	width: 35rpx;
	height: 35rpx;
}

.delete-icon {
	width: 55rpx;
	height: 40rpx;
	margin-top: 18rpx;
}
复制代码

json文件,标识出来这是一个component

{
  "component": true
}
复制代码

在页面里如何使用呢

要在json里引用组件

{
  "usingComponents": {
    "carKeyboard": "/components/carKeyboard/carKeyboard"
  }
}
复制代码

<view class="container">
  <view>
    <button class="btn" bindtap="inputCarNum">输入车牌号button>
  view>
<block wx:if="{{showKeyboard}}">
  <carKeyboard
      carNum="{{carNum}}"
      bind:onOk="onOk"
      bind:onCancel="onCancel"
  />
block>
view>



复制代码
//index.js

Page({
  data: {
    carnum: '',
    showKeyboard:false,
  },
  inputCarNum() {
    this.setData({showKeyboard: true})
  },
 
  onOk(e){
    console.log(e.detail,'输入的车牌号')
  },
  onCancel(){
    this.setData({ showKeyboard: false   })
  }
})
复制代码

转载于:https://juejin.im/post/5c4e7069e51d454b0d75d3db

你可能感兴趣的:(小程序--自定义键盘车牌号)