uniapp 之 新能源键盘 以及 验证码倒计时

效果图

备注

新能源输入 车牌 输入规则 第三位必为 D 或 F ,第四位可以是字母也可以是数字 但最后四位必为数字,

在测车牌号校验时 总提示输入错误,最后才发现 上面的输入规则

代码

<template>
  <view class="container">
    <view class="form userform">
      <view class="username">
        <input style="width: 70%;" placeholder="请输入手机号" v-model="mobileNumber" />
        <view class="get-code" :style="{'color':getCodeBtnColor}" @click.stop="getCode()">{{getCodeText}}
        </view>
      </view>
      <view class="code">
        <input placeholder="请输入验证码" v-model="code" />
      </view>
      <view class="car_number_input">
        请输入车牌号
        <view class="car_type" @click.stop="keyShow = !keyShow">
          <view class="default_car">
            <view class="" v-show="carNumber[0]">
              {{carNumber[0]}}
            </view>
            <view class="line" v-show="!carNumber[0]">
              __
            </view>
          </view>
          <view class="default_car">
            <view class="" v-show="carNumber[1]">
              {{carNumber[1]}}
            </view>
            <view class="line" v-show="carNumber[0] && !carNumber[1]">
              __
            </view>
          </view>
          <view class="default_car">
            <view class="" v-show="carNumber[2]">
              {{carNumber[2]}}
            </view>
            <view class="line" v-show="carNumber[0] && carNumber[1] && !carNumber[2]">
              __
            </view>
          </view>
          <view class="default_car">
            <view class="" v-show="carNumber[3]">
              {{carNumber[3]}}
            </view>
            <view class="line" v-show="carNumber[0] && carNumber[1] && carNumber[2] && !carNumber[3]">
              __
            </view>
          </view>
          <view class="default_car">
            <view class="" v-show="carNumber[4]">
              {{carNumber[4]}}
            </view>
            <view class="line" v-show="carNumber[0] && carNumber[1] && carNumber[2] && carNumber[3] && !carNumber[4]">
              __
            </view>
          </view>
          <view class="default_car">
            <view class="" v-show="carNumber[5]">
              {{carNumber[5]}}
            </view>
            <view class="line"
              v-show="carNumber[0] && carNumber[1] && carNumber[2] && carNumber[3] && carNumber[4] && !carNumber[5]">
              __
            </view>
          </view>
          <view class="default_car">
            <view class="" v-show="carNumber[6]">
              {{carNumber[6]}}
            </view>
            <view class="line"
              v-show="carNumber[0] && carNumber[1] && carNumber[2] && carNumber[3] && carNumber[4] && carNumber[5] && !carNumber[6]">
              __
            </view>
          </view>
          <view class="default_car">
            <view class="" v-show="carNumber[7]">
              {{carNumber[7]}}
            </view>
            <view class="line"
              v-show="carNumber[0] && carNumber[1] && carNumber[2] && carNumber[3] && carNumber[4] && carNumber[5] && carNumber[6] && !carNumber[7]">
              __
            </view>
          </view>
        </view>
      </view>

      <view class="tips">
        注:请输入真实有效的车牌号
      </view>
      <view class="btn" @tap="pileBtn">请确认填入信息</view>
    </view>
    <!-- 键盘 -->
    <view class="keyboard-content" v-show="keyShow">
      <!-- 省份键盘 -->
      <template v-if="provinceBoardShow">
        <view class="province-keyboard flex">
          <view class="td td-nor color-333" v-for="(item,index) in provincesKeyList" :key="index"
            @click="provinceKeyClick(item,index)" hover-class="board-active" hover-start-time="0" hover-stay-time="80">
            {{item}}
          </view>
        </view>
      </template>
      <!--数字键盘-->
      <template v-if="!provinceBoardShow">
        <view class="number-keyboard flex between">
          <template>
            <view class="td td-num color-333" :class="numberIsDis ? 'board-active' : ''"
              v-for="(item,index) in numberKeyList" :key="index" @click="numberKeyClick(item,index)"
              :hover-class="numberIsDis ? '' : 'board-active'" hover-start-time="0" hover-stay-time="80">
              {{item}}
            </view>
          </template>
        </view>
      </template>
      <!--字母键盘-->
      <template v-if="!provinceBoardShow">
        <view class="english-keyboard flex between">
          <template>
            <view class="td td-num color-333" :class="englishIsDis ? 'board-active' : ''"
              v-for="(item,idx) in englishKeyOneList" :key="idx" @click="englishKeyClick(item,idx)"
              :hover-class="englishIsDis ? '' : 'board-active'" hover-start-time="0" hover-stay-time="80">
              {{item}}
            </view>
          </template>
        </view>
        <!-- 最后一行 -->
        <view class="english-keyboard flex englishtTwo">
          <template>
            <view class="td td-num color-333" :class="englishIsDis ? 'board-active' : ''"
              v-for="(item,index) in englishKeyTwoList" :key="index" @click="englishKeyClick(item,index)"
              :hover-class="englishIsDis ? '' : 'board-active'" hover-start-time="0" hover-stay-time="80">
              {{item}}
            </view>
          </template>
        </view>
      </template>
    </view>
    <!--清除按钮-->
    <view @click.stop="backspace" class="delete flex" v-if="keyShow">清除</view>
    <view @click.stop="sure" class="sure flex" v-if="keyShow">确定</view>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        // 手机号
        mobileNumber: "",
        // 验证码
        code: '',
        passwd: "",
        getCodeText: '获取验证码',
        getCodeBtnColor: "black",
        getCodeisWaiting: false,
        pileCode: '',
        carClick: false,
        keyShow: false, // 键盘是否显示
        sureColor: false,
        current: 0,
        carNumber: [],
        currentIndex: 0,
        provincesKeyList: '京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新',
        provinceBoardShow: true, // 省键盘
        numberKeyList: '0123456789',
        numberIsDis: true, // 输入键盘不可点击 true为不可点击
        englishIsDis: false, // 字母键盘可点击
        englishKeyOneList: 'ABCDEFGHJKLMNPQRSTUVWX',
      };
    },
    onLoad() {},
    onShow() {},
    methods: {
      // 确定桩号按钮
      pileBtn() {
        uni.hideKeyboard() //隐藏已经显示的软键盘,如果软键盘没有显示则不做任何操作。
        //模板示例部分验证规则
        if (!(/^1(3|4|5|6|7|8|9)\d{9}$/.test(this.mobileNumber))) { //校验手机号码
          uni.showToast({
            title: '请填写正确手机号码',
            icon: "none"
          });

          return false;
        }
        //示例验证码,实际使用中应为请求服务器比对验证码是否正确。
        if (this.code == '') {
          uni.showToast({
            title: '请输入验证码',
            icon: "none"
          });

          return false;
        }
        let arr = this.carNumber.join('')
        console.log(arr);
        // this.keyShow = true
        if (!this.checkPlateNumber(arr)) { // 校验桩号 this.passwd == ''
          uni.showToast({
            title: '请输入正确的车牌号',
            icon: "none"
          });
          return false
        }
        uni.showLoading({
          title: '提交中...'
        })
        this.bindingCarNo() // TODO 绑定车辆请求

      },
      // 绑定车牌号
      async bindingCarNo() {
        let arr = this.carNumber.join('')
        console.log(arr);
        let params = {
          phoneNumber: this.mobileNumber,
          verificationCode: this.code,
          carNo: arr
        }

        const { data: { obj, resCode, msg } } = await uni.$http.post('/uniapp/member/memberBindingCarNo', params)
        console.log('memberBindingCarNo 绑定车牌号发送请求 ', resCode, msg);
        if ('00100000' !== resCode) return uni.showMsg(msg)
        // 返回上一页
        uni.navigateBack({
          delta: 1
        })
      },
      getCode() {
        uni.hideKeyboard() //隐藏已经显示的软键盘,如果软键盘没有显示则不做任何操作。
        if (this.getCodeisWaiting) {
          return;
        }
        if (!(/^1(3|4|5|6|7|8|9)\d{9}$/.test(this.mobileNumber))) { //校验手机号码是否有误
          uni.showToast({
            title: '请填写正确手机号码',
            icon: "none"
          });
          return false;
        }
        this.getCodeText = "发送中..." //发送验证码
        this.verification()
        this.getCodeisWaiting = true;
        this.getCodeBtnColor = "black"
        setTimeout(() => {
          uni.showToast({
            title: '验证码已发送',
            icon: "none"
          }); //弹出提示框
          this.setTimer();
        }, 1000)
      },
      // 获取验证码的方法
      async verification() {
        // console.log("手机号", this.mobileNumber)
        const res = await uni.$http.post('/uniapp/member/sendSMS', {
          mobileNumber: this.mobileNumber
        })
        console.log(res, '验证码信息');
      },
      setTimer() {
        let holdTime = 60; //定义变量并赋值
        this.getCodeText = "重新获取(60)"
        this.Timer = setInterval(() => {
          if (holdTime <= 0) {
            this.getCodeisWaiting = false;
            this.getCodeBtnColor = "#ffffff";
            this.getCodeText = "获取验证码"
            clearInterval(this.Timer); //清除该函数
            return; //返回前面
          }
          this.getCodeText = "重新获取(" + holdTime + ")"
          holdTime--;
        }, 1000)
      },
      typeCurrent() {
        this.carClick = true
        this.carNumber = []
        this.current = 0
        console.log('点击哪个地方的', this.current);
        this.provinceBoardShow = true
        this.numberIsDis = true;
        this.englishIsDis = true

      },
      // 省份键盘
      provinceKeyClick(val, index) {
        this.carNumber[0] = val
        this.provinceBoardShow = false
        this.numberIsDis = true;
        this.englishIsDis = false
        this.current++

        console.log(this.current, '省份current')
      },
      // 数字键盘
      numberKeyClick(val, idx) {
        console.log(this.carNumber.length, 'this.carNumber.length00')
        if (this.numberIsDis) return
        if (this.carNumber.length >= 7) {
          this.sureColor = true
        }
        if (this.carNumber.length >= 8) return
        this.current++
        this.carNumber[this.current - 1] = val;
        // this.setTrailerKeyboardDis()

        console.log(this.current, '数字键盘current')
      },
      // 字母键盘
      englishKeyClick(val, idx) {
        console.log(this.currentIndex, this.carNumber.length, 'this.carNumber.length')
        if (this.englishIsDis) return
        if (this.carNumber.length >= 7) {
          this.sureColor = true
        }
        if (this.carNumber.length >= 8) {
          console.log(this.carNumber);
          this.keyShow = false
        }
        this.current++
        this.carNumber[this.current - 1] = val;
        if (this.current == 2) this.numberIsDis = false;

        console.log(this.current, 'current')
      },

      sure() {
        // console.log(this.carNumber);
        let arr = this.carNumber.join('')
        console.log(arr);
        // this.keyShow = true
        if (!this.checkPlateNumber(arr)) { // 校验桩号 this.passwd == ''
          uni.showToast({
            title: '请输入正确的车牌号',
            icon: "none"
          });
          return false
        }
        this.keyShow = !this.keyShow
        // let carString = this.carNumber.join(',')
        console.log(this.carNumber);
      },
      backspace() {
        console.log(this.current, 'current')
        if (this.current <= 1) {
          this.provinceBoardShow = true
          this.numberIsDis = true
          this.englishIsDis = true

        }
        if (this.current <= 0) return
        this.current--
        this.carNumber.pop()
        // this.$forceUpdate()
      },
      addCar() {
        if (this.sureColor == false) {
          this.$u.toast('请输入有效的车牌号')
          return false
        }
        this.keyShow = false
        console.log(this.carNumber, 'carn')
      },
      checkPlateNumber(carNumber) {
        // const re = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-Z0-9][0-9]{4}$))/
        const re =
          /^([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[a-zA-Z](([DF]((?![IO])[a-zA-Z0-9](?![IO]))[0-9]{4})|([0-9]{5}[DF]))|[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1})$/
        const reg = new RegExp(re)
        return reg.test(carNumber)
      },
    }
  }

</script>

<style lang="scss" scoped>
  @keyframes fade {
    from {
      opacity: 1.0;
    }

    50% {
      opacity: 0;
    }

    to {
      opacity: 1.0;
    }
  }

  @-webkit-keyframes fade {
    from {
      opacity: 1.0;
    }

    50% {
      opacity: 0;
    }

    to {
      opacity: 1.0;
    }
  }

  .flex {
    display: flex;
  }

  .between {
    justify-content: space-between;
  }

  .font-30 {
    font-size: 30rpx;
  }

  .color-333 {
    color: #333333;
  }

  .container {
    padding: 20rpx;
    color: black;

    .car_number_input {
      margin-top: 42rpx;

      .car_type {
        display: flex;
        justify-content: start;
        margin: 0 auto;

        .default_car {
          width: 98rpx;
          height: 98rpx;
          border: 1rpx solid #999999;
          text-align: center;
          line-height: 98rpx;
          font-size: 40rpx;
          font-family: PingFang SC;
          font-weight: bold;
          color: #333333;

          .line {
            color: #EA4070;
            border-radius: 2px;
            animation: fade 1500ms infinite;
            -webkit-animation: fade 1500ms infinite;
          }
        }

        .default_car:nth-child(1) {
          border-right: none;
        }

        .default_car:nth-child(2) {
          border-right: none;
          color: #EA4070;
        }

        .default_car:nth-child(3) {
          border-right: none;
          color: #EA4070;
        }

        .default_car:nth-child(4) {
          border-right: none;
          color: #EA4070;
        }

        .default_car:nth-child(5) {
          border-right: none;
          color: #EA4070;
        }

        .default_car:nth-child(6) {
          border-right: none;
          color: #EA4070;
        }

        .default_car:nth-child(7) {
          color: #EA4070;
        }

        .default_car:nth-child(8) {
          border-left: none;
          color: #EA4070;
        }
      }
    }

    .tips {
      font-size: 28rpx;
      font-family: PingFang SC;
      font-weight: 500;
      color: #999999;
      margin-bottom: 27rpx;
      // text-align: center;
    }

    .add_car_box {
      float: left;
      width: calc(100% - 64rpx);
      height: 80rpx;
      background: linear-gradient(180deg, #DF4270, #F299AB);
      border-radius: 45upx;
      margin: 0 auto;

      .add_car {
        height: 100%;
        line-height: 80rpx;
        font-size: 34rpx;
        font-weight: 500;
        color: #FFFFFF;
        text-align: center;
      }

      .dis_car {
        height: 100%;
        line-height: 80rpx;
        font-size: 34rpx;
        font-weight: 500;
        color: #FFFFFF;
        background: #999999;
        text-align: center;
        border-radius: 40px;
      }
    }

    .keyboard-content {
      width: 100%;
      height: 450rpx;
      box-sizing: border-box;
      position: fixed;
      bottom: 0;
      left: 0;
      background-color: #D2D6D9;

      .td {
        font-family: "PingFangSC";
        font-size: 34rpx;
        color: #333333;
        font-weight: 500;
        margin: 12rpx 4rpx;
        border: 1rpx solid #E0E0E0;
        border-radius: 8rpx;
        height: 84rpx;
        line-height: 84rpx;
        text-align: center;
        background-color: #fff;
      }

      .province-keyboard {
        margin: 0 5rpx;
        flex-wrap: wrap;

        .td-nor {
          flex: 0 1 8%;
          // margin-right: 3px;
        }
      }

      .number-keyboard {
        margin: 0 5rpx;

        .td-num {
          flex: 0 1 8%;
        }

        .board-active {
          box-shadow: 0 0 0 #e5e5e5;
          background: #e5e5e5;
        }
      }

      .english-keyboard {
        margin: 0 5rpx;
        flex-wrap: wrap;

        &.englishtTwo {
          // margin-left: 80rpx;

          .td-num {
            margin-right: 5px;
            flex: 0 1 8%;
          }
        }

        .td-num {
          flex: 0 1 8%;
        }

        .board-active {
          box-shadow: 0 0 0 #e5e5e5;
          background: #e5e5e5;
        }
      }
    }

    .delete {
      width: 100rpx;
      height: 84rpx;
      text-align: center;
      background-color: #AFB2BC;
      border-radius: 8rpx;
      position: absolute;
      right: 120rpx;
      bottom: 30rpx;
      justify-content: center;
      align-items: center;
    }

    .sure {
      width: 100rpx;
      height: 84rpx;
      text-align: center;
      background-color: #AFB2BC;
      border-radius: 8rpx;
      position: absolute;
      right: 10rpx;
      bottom: 30rpx;
      justify-content: center;
      align-items: center;
    }
  }

  .form {
    width: 86%;
    padding: 0 7%;
    font-size: 30upx;

    .username,
    .password,
    .code {
      width: calc(100% - 90upx);
      height: 90upx;
      display: flex;
      align-items: center;
      border-radius: 45upx;
      background-color: rgba($color: black, $alpha: 0.1);
      padding: 0 45upx;
      margin-bottom: 26upx;

      input {
        width: 100%;
        height: 50upx;
        // color: rgba($color: #ffffff, $alpha: 0.8);
        font-weight: 200;
      }
    }

    .btn {
      color: #f06c7a;
      width: 100%;
      height: 90upx;
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 45upx;
      // background-color: #fff;
      font-size: 40upx;
    }

    .userform {
      .username {
        position: relative;

        .get-code {
          position: absolute;
          height: 90upx;
          display: flex;
          align-items: center;
          justify-content: center;
          right: 0;
          padding: 0 40upx;
          z-index: 3;

          &:after {
            //点击以后,左边出现白色的线
            content: " ";
            width: 1upx; //宽度为1upx
            height: 50upx; //高度为50upx
            // background-color: #fff; //背景颜色为白色
            position: absolute;
            z-index: 3;
            margin-right: 100%;
            left: 0;
            top: 20upx;
          }
        }
      }
    }
  }

</style>

注意

我这边 绑定成功后 使用的是 navigateBack 返回上一页,那只能使用 navigateTo 跳转到注册页,

还有使用 navigateBack 返回上一页时 它不会自动刷新数据,因此 在 使用 navigateTo 方法的页面中   在 onShow 里发送请求 ,不要在onLoad 发送请求

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值