小程序自定义键盘和输入框组件(可用于支付密码弹框和短信验证码)

260 阅读2分钟

先看一下效果

在这里插入图片描述

组件wxml代码

<!--components/keyboard_number/keyboard_number.wxml-->
<view class="mk-click" bindtap="onShowKeyboard"></view>

<view class="keyboard-main-container" catchtouchmove="true" style="pointer-events:{{isShowModal ? 'all': 'none'}}">
  <view class="bg-click {{isShowModal ? 'bg-click-ac': ''}}" bindtap="onCloseKeyboard"></view>

  <view class=" keyboard-input-container">
    <view class="password-container {{isShowModal ? 'pwd-ac' : 'pwd-un'}}">
      <view class="title">
        <view></view>
        <text class="title-txt">请输入支付密码</text>
        <view style="font-size:30rpx;font-weight:800" bindtap="onCloseKeyboard">X</view>
      </view>
      <view class="fee-money">12</view>
      <view class="input-value-container">
        <view class="value-item" wx:for="{{pwdVal}}" data-val="{{item}}" wx:key="index">{{item}}</view>
      </view>
    </view>
    
    <view class="keyboard-number-container {{isShowModal ? 'number-box-ac': ''}}">
      <view class="number-item" wx:for="{{keyboardNumList}}" wx:key="index" data-index="{{index}}" data-val="{{item}}" bindtap="handKeyboardChange">{{item}}</view>
      <view class="number-item" bindtap="onClearPwd">X</view>
    </view>
  </view>
</view>

组件wxss代码

/* components/keyboard_number/keyboard_number.wxss */
.mk-click{
  position: absolute;
  top: 0;
  left: 0;
  z-index: 9;
  width: 100%;
  height: 100%;
}
.bg-click{
  width: 100vw;
  height: 100vh;
  position: fixed;
  z-index: -1;
  top: 0;
  left: 0;
  right: 0;
  opacity: 0;
  background-color: rgba(75, 74, 74, 0.5);
  transition: opacity cubic-bezier(0, 1.05, 0.6, 1.01) .5s;
}
.bg-click-ac{
  opacity: 1;
}
.keyboard-input-container{
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: center;
  width: 100vw;
}
/* 密码输入框 */
.password-container{
  display: flex;
  align-items: center;
  flex-direction: column;
  width: 600rpx;
  padding: 30rpx;
  margin-top: 50rpx;
  border-radius: 15rpx;
  background-color: #fff;
}
.title{
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}
.title-txt{
  font-size: 35rpx;
}
.fee-money{
  margin: 20rpx 0;
  font-size: 50rpx;
  font-weight: bolder;
}
.fee-money::before{
  content: '¥';
  font-size: 30rpx;
  font-weight: 600;
}
.input-value-container{
  display: flex;
  align-items: center;
  justify-content: space-between;
  text-align: center;
  border-radius: 10rpx;
  margin-bottom: 10rpx;
  background-color: #fff;
  border: 1px solid #e5e5e5;
}
.value-item{
  width: 90rpx;
  height: 85rpx;
  line-height: 85rpx;
  font-weight: bolder;
  border-right: 1px solid #e5e5e5;
}
.pwd-ac{
  transform: scale(1);
}
.pwd-un{
  transform: scale(0);
}
.value-item:last-child{
  border-right: 0;
}
/* 数字键盘 */
.keyboard-number-container{
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding-bottom: 50rpx;
  background-color: #f9f9fa;
  border-top: 1px solid #f9f9fa;
  box-shadow: 2rpx 10rpx 5rpx #f9f9fa;
  background-color: #f9f9fa;
  transform: translateY(680rpx);
  transition: transform cubic-bezier(0, 1.05, 0.6, 1.01) .7s;
}
.number-item{
  width: 33%;
  line-height: 120rpx;
  color: #333;
  font-size: 35rpx;
  font-weight: bolder;
  text-align: center;
  border-bottom: 1px solid #f9f9fa;
  border-right: 1px solid #f9f9fa;
  background-color: #fff;
}
.number-box-ac{
  transform: translateY(0);
}
.number-item:not(:nth-child(3n)){
  border-right: 0;
}
.number-item:active{
  background-color: #f9f9fa;
}

组件js代码

// components/keyboard_number/keyboard_number.js

Component({
  /**
   * 组件的属性列表
   */
  properties: {
    //是否显示小数点
    isShowPoint: {
      type: Boolean,
      value: true
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    //是否弹出
    isShowModal: true,
    index: 0,
    pwdVal: ['','','','','',''],
    // 键盘列表
    keyboardNumList: [1,2,3,4,5,6,7,8,9,'.',0]
  },
  observers: {
    isShowPoint(newVal,oldVal){
      console.log(newVal)
      let { keyboardNumList } = this.data
      //根据传值判断是否显示小数点
      if(!newVal){
        let boardArr = keyboardNumList.filter((item) =>{
          return item !== "."
        })
        this.setData({
          keyboardNumList: boardArr
        })
      }
    }
  },
  /**
   * 组件的方法列表
   */
  methods: {
    //点击数字键盘
    handKeyboardChange(e){
      let { pwdVal, index, keyboardNumList } = this.data
      let { val }  = e.currentTarget.dataset
      if(index > 5){
        wx.showToast({
          title: '不能再输入了',
        })
      } else {
        let arr = pwdVal
        // console.log(arr)
        // 根据index向数组中追加对应的数据
        arr.splice(index, 1, val)
        this.setData({
          pwdVal: arr,
          index: index + 1,
        })
      }
    },
    //删除密码
    onClearPwd(){
      let { pwdVal, index } = this.data
      if(index === 0){
        wx.showToast({
          title: '不能再删除了',
        })
        return
      }
      let arr = pwdVal;
      arr.splice(index - 1, 1, '')
      this.setData({
        pwdVal: arr,
        index: index - 1,
      })
      console.log(this.data.pwdVal)
    },
    //显示弹框
    onShowKeyboard(){
      this.setData({
        isShowModal: true
      })
    },
    //关闭弹框
    onCloseKeyboard(){
      this.setData({
        isShowModal: false,
        pwdVal: ['','','','','','']
      })
    }
  }
})

使用方法

在json文件中引入组件,然后调用

<keyboard_number isShowModal="{{false}}" />

注意:

1、不要忘记在父组件对应的父元素中设置:position: relative

2、想要那种验证码格式的只需要简单改一下样式就可以了

3、密码框想要点点点格式的自己用js的`replace`或者**repeat**方法替换一下就可以,这里就不写了