input 验证码 密码 输入框

前言:uniapp  在做需求的时候,经常会遇到;验证码输入框  或者 密码输框  自定义样式输入框  或者 格式化显示 银行卡 手机号码等等:这里总结了两种 常用的实现方式;

从这两种实现方式 其实也能延伸出其他的显示 方式;

先看样式: 自己实现 光标闪烁动画

第一种:可以识别 获得焦点 失去焦点

第一种实现的思路

      实际上就是,下层的真实  input 负责响应系统的输入,上面一层负责显示

      应为输入框在手机端会 出现长按 学着 复制等等 输入框自带属性:这里的处理思路是:  拉长输入框,延伸到屏幕以外; 这样就不会出现 系统出现的一些选项,但是有时候 还会有个别情况!(可能性很低)

   position: absolute;
        color: #8cff21;
        background-color: rgba($color: #ff1702, $alpha: 0.2);
        left: -150%;
        height: 100%;
        width: 300%;

这里其实可以延伸出 其他的个性化显示方式比如:  银行卡号 中间带空格这种

第二种: 完全撇开 input, 自己实现输入 软键盘

完整代码:

  • uniapp 方向;
  • 依赖官方 uni-popup

工程下载icon-default.png?t=M3K6https://download.csdn.net/download/nicepainkiller/85214409

<template>
  <view class="content">
    <view class="title-input-1">
      方式1:{
   
   {inputFocus1}}
    </view>
    <view class="input-box-1">
      <input type="number" :focus="inputFocus1" value="" v-model="inputText1" class="input-number" @input="onInput1"
        @focus="onFocus1" @blur="onBlur1" maxlength="4" />
      <view class="number-box">
        <view class="number-item" v-for="(item,index) in inputText1Cache1" :key="index">
          <view class="item-number" v-if="item">
            {
   
   {item}}
          </view>
          <view class="item-focus" v-else-if="inputFocus1&&onShowFocus1(index)">
          </view>
        </view>
      </view>  
    </view>
    <view class="title-input-2">
      方式2:
    </view>
    <view class="input-box-2">
      <!--      <input type="number" value="" v-model="inputText2" class="input-number" @input="onInput2" @focus="onFocus2"
        @blur="onBlur2" maxlength="4" /> -->
      <view class="number-box" @click="onOpenInput2()">
        <view class="number-item" v-for="(item,index) in inputText2Cache1" :key="index">
          <view class="item-number" v-if="item">
            {
   
   {item}}
          </view>
          <view class="item-focus" v-else-if="inputFocus2&&onShowFocus2(index)">
          </view>
        </view>
      </view>
    </view>

    <uni-popup ref="uniPopup" type="bottom" mask-background-color="rgba(0,0,0,0.0)" @maskClick="onMask">
      <view class="number-content">
        <view class="content-top">
          <view class="number-item" v-for="(item,index) in softNumbers" :key="index" @click="inputNumber(item)">
            {
   
   {item}}
          </view>
        </view>
        <view class="content-bottom">
          <view class="number-item" v-for="(item,index) in softNumbersBottom" :key="index" @click="inputDele(index)">
            {
   
   {item}}
          </view>
        </view>
      </view>
    </uni-popup>

  </view>
</template>

<script>
  export default {
    data() {
      return {
        inputText1: '',
        inputFocus1: false,
        inputText1Cache1: [, , , , ],

        inputText2: '',
        inputFocus2: false,
        inputText2Cache1: [, , , , ]
      }
    },
    onLoad() {

    },
    computed: {
      softNumbers() {
        return ['1', '2', '3', '4', '5', '6', '7', '8', '9']
      },
      softNumbersBottom() {
        return ['', '0', '←']
      }
    },
    methods: {
 

      onShowFocus1(index) {
        if (index < this.inputText1.length + 1) {
          return true
        } else {
          return false
        }
      },
      onInput1(e) {
        console.log('e.detail:', e.detail)

        this.$nextTick(function() {
          this.inputText1Cache1 = [, , , , ]
          for (let i = 0; i < this.inputText1.length; i++) {
            this.inputText1Cache1[i] = this.inputText1[i]
          }
          if (this.inputText1.length === 4) {
            console.log('输入完成!')
            uni.showToast({
              icon: "none",
              position: 'bottom',
              title: `输入完成!:${this.inputText1}`
            })
          }
        })

      },
      onInput1Fouse() {
        this.inputFocus1 = true
      },
      onFocus1() {
        console.log('输入框1得到焦点')
        this.inputFocus1 = true
      },
      onBlur1() {
        console.log('输入框1失去焦点')
        this.inputFocus1 = false
      },




      onMask() {
        console.log("onMask:")
        this.inputFocus2 = false
      },
      onShowFocus2(index) {
        if (index < this.inputText2.length + 1) {
          return true
        } else {
          return false
        }
      },
      maskClick() {

      },
      onOpenInput2() {
        console.log('输入框2得到焦点')
        this.inputFocus2 = true
        this.$refs.uniPopup.open()
      },

      inputNumber(item) {
        if (this.inputText2.length >= 4) {
          this.$refs.uniPopup.close()
          return
        }
        this.inputText2 += item
        this.$nextTick(function() {
          this.inputText2Cache1 = [, , , , ]
          for (let i = 0; i < this.inputText2.length; i++) {
            this.inputText2Cache1[i] = this.inputText2[i]
          }
          if (this.inputText2.length === 4) {
            console.log('输入完成!')
            this.$refs.uniPopup.close()
            uni.showToast({
              icon: "none",
              position: 'bottom',
              title: `输入完成!:${this.inputText2}`
            })
          }

          // console.log("inputText2:", this.inputText2)
          // console.log(" this.inputText2Cache1:", this.inputText2Cache1)
        })



      },
      inputDele(index) {
        if (index === 1) {
          if (this.inputText2.length >= 4) {
            this.$refs.uniPopup.close()
            return
          }
          this.inputText2 += '0'
          this.inputText2Cache1 = [, , , , ]
          for (let i = 0; i < this.inputText2.length; i++) {
            this.inputText2Cache1[i] = this.inputText2[i]
          }
          if (this.inputText2.length === 4) {
            this.$refs.uniPopup.close()
            //console.log('输入完成!')
            uni.showToast({
              icon: "none",
              position: 'bottom',
              title: `输入完成!:${this.inputText2}`
            })
          }
        } else if (index === 2) {
          if (this.inputText2.length > 0) {
            this.inputText2 = this.inputText2.substr(0, this.inputText2.length - 1)
            console.log("this.inputText2:", this.inputText2)
            this.inputText2Cache1 = [, , , , ]
            for (let i = 0; i < this.inputText2.length; i++) {
              this.inputText2Cache1[i] = this.inputText2[i]
            }
          }
        }
      }
    }
  }
</script>

<style lang="scss" scoped>
  .content {
    .title-input-1 {
      padding-left: 24rpx;
      margin-top: 50rpx;
    }

    .input-box-1 {
      position: relative;
      margin: 0 auto;
      background-color: #000000;
      width: 95%;
      height: 88rpx;
      margin-top: 50rpx;




      .input-number {
        position: absolute;
        color: #8cff21;
        background-color: rgba($color: #ff1702, $alpha: 0.2);
        left: -150%;
        height: 100%;
        width: 300%;
      }

      .number-box {
        position: absolute;
        top: 0;
        height: 100%;
        width: 100%;
        background-color: #007AFF;
        pointer-events: none;

        display: flex;
        flex-direction: row;
        justify-content: space-around;
        align-items: center;

        .number-item {
          position: relative;
          width: 86rpx;
          height: 86rpx;
          background-color: #FFFFFF;
          border: 1px solid #000000;
          line-height: 86rpx;
          text-align: center;

          pointer-events: none;

          .item-number {}

          .item-focus {

            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 2px;
            height: 50rpx;
            background-color: #0c0b0a;
            animation: flicker 1s linear 0s infinite;


          }
        }
      }

    }

    .title-input-2 {
      padding-left: 24rpx;
      margin-top: 120rpx;

    }

    .input-box-2 {
      position: relative;
      margin: 0 auto;
      background-color: #000000;
      width: 95%;
      height: 88rpx;
      margin-top: 50rpx;

      .input-number {
        color: #FFFFFF;
        background-color: rgba($color: #ff1702, $alpha: 0.2);
        height: 100%;
        width: 100%;
      }

      .number-box {
        position: absolute;
        top: 0;
        height: 100%;
        width: 100%;
        background-color: #ffb520;
        // pointer-events: none;

        display: flex;
        flex-direction: row;
        justify-content: space-around;
        align-items: center;

        .number-item {
          position: relative;
          width: 86rpx;
          height: 86rpx;
          background-color: #FFFFFF;
          border: 1px solid #000000;
          line-height: 86rpx;
          text-align: center;


          .item-number {}

          .item-focus {

            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 2px;
            height: 50rpx;
            background-color: #0c0b0a;
            animation: flicker 1s linear 0s infinite;


          }
        }
      }

    }

    .number-content {
      width: 100%;
      height: 400rpx;
      background-color: #dddddd;

      .content-top {
        height: 300rpx;
        width: 100%;
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        // background-color: #18BC37;
        justify-content: center;

        .number-item {
          position: relative;
          // background-color: #2979FF;
          height: 100rpx;
          width: 33%;
          color: #333333;
          line-height: 100rpx;
          text-align: center;
          border-bottom: 1px solid #FFFFFF;
        }

        .number-item:nth-child(3n+2) {
          border-left: 1px solid #FFFFFF;
          border-right: 1px solid #FFFFFF;
        }
      }

      .content-bottom {
        height: 100rpx;
        width: 100%;
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        // background-color: #18BC37;
        justify-content: center;

        .number-item {
          position: relative;
          // background-color: #2979FF;
          height: 100rpx;
          width: 33%;
          color: #333333;
          line-height: 100rpx;
          text-align: center;
        }

        .number-item:nth-child(3n+2) {
          border-left: 1px solid #FFFFFF;
          border-right: 1px solid #FFFFFF;
        }
      }
    }


    @keyframes flicker {
      0% {
        background-color: rgba($color: #0c0b0a, $alpha: 1);
      }

      100% {
        background-color: rgba($color: #0c0b0a, $alpha: 0.3);
      }
    }
  }
</style>

猜你喜欢

转载自blog.csdn.net/nicepainkiller/article/details/124384995
今日推荐