美文网首页Vue
【经验分享】VUE中短信验证码六位数字框输入设计

【经验分享】VUE中短信验证码六位数字框输入设计

作者: 度一特 | 来源:发表于2020-10-07 23:58 被阅读0次

    更新

    1. 2020/10/8 更新
    • 如果是输入文字的时候,将插入内容为空,同时焦点依然是在当前的文本框
    • 去掉Formulate组建,直接使用input
    • 在加载的时候如果vux中没有短信内容,将页面跳转到login登录

    本文主要目标

    1、实现六位数字框的排列效果,具体特点是使用flex布局
    2、实现六位数字框的脚本控制,输入数字自动跳转到下一数字框
    3、实现过60秒后再发送短信码

    主要技术要点

    1、六个数字框架需要使用脚本进行控制,具体为,设置ref,在method中获得对象;

    <div ref="vertifyWrapper">
    <FormulateInput input-class="login_input" />
    

    methods

    let vertifyInputArray = this.$refs.vertifyWrapper.getElementsByClassName("login_input");
    

    2、设定keyup的事件,主要实现输入以后,自动跳转到下一个数字框,在最后一个输入框,自动将留个框的数字组合,提交post内容

    3、设定keydown的事件,主要的目的是避免用户多输入文字

    4、六位数字自动排列,主要是使用flex,这里面用到了tailwindcss
    (Tailwindcss确实是减少了大量的代码书写,实际使用中是将Tailwind实现大框架,自己的css作为辅助)

    <div class="mt-4 flex px-1 text-center item-center" ref="vertifyWrapper">
             <FormulateInput v-for="index in 6" :key="index" 
              outer-class="w-2/12" inputmode="numeric" 
               />
     </div>
    

    其他技术情况

    1、使用了TailwindCss框架快速实现了六个框的排列效果,关于TailwindCss,请参看以前文章(使用普通CSS也可以实现)
    【TailwindCSS】帮你快速实现定制CSS的平台【Tailwind CSS】介绍以及在Vue的使用

    2、使用了Vue Formulate的表单框架(普通的INPUT配样式也可以)

    具体代码

    VertifyMobile.vue

    <template> 
      <div class="bg-white w-full fixed h-full">
        <NavHeader></NavHeader>
    
        <div class="px-6" style="margin-top:45px;">
          <div class="text-center text-jpfont-800 " style="font-weight: 500; line-height:28px; font-size:14px;padding-top:28px;padding-bottom:12px;">
            <div class="text-center item-center w-full" style="padding-left: 45%">
              <i>
                <svg-icon icon-class="vertifycode" class-name="vertifycodeIcon" />
              </i>
            </div>
            <div>验证码将以短信的形式发送给您,请注意接收。</div>
          </div>
    
          <div class="ml-2 mt-4 flex px-1 text-center item-center" ref="vertifyWrapper">
           
              <input type="number" v-for="index in 6"   :key="index" class="w-2/12 login_input" @keydown='clearInput' @keyup='goVertify'/>
    
          </div>
          <div class="mt-8 flex">
            <div class="text-sm text-jpcolor-500 pl-3" @click="getVertifycode" :class="[{ hidden: !isShowVertifyCode }]">获取验证码</div>
            <div class="text-sm text-jpfont-400 pl-3" :class="[{ hidden: isShowVertifyCode }]">重新发送({{timersecond}})</div>
          </div>
        </div>
    
    
         <!-- 提示信息 start -->
        <div class="InfoWrapper" :class="[{ hidden: !isShowPromptInfo }, { flex: isShowPromptInfo } ]">
          <div style="height:30%;width:100%;"></div>
          <div class="mainWrapper">
              <div class="text-center item-center w-full" style="padding-left: 40%;margin-bottom: 12px;">
                <i>
                  <svg-icon icon-class="info" class-name="infoIcon" />
                </i>
              </div>
              <div>{{promptInfo}}</div>
          </div>
        </div>
        <!-- 提示信息 end -->
    
      </div> 
    </template>
    
    <script>
    import { mapState } from 'vuex'
    import NavHeader from "./NavHeader.vue";
    
    export default {
      data() {
        return {
          inputMobile: "",
          isFocus : false,
          inputVertifyCode : [],
          currentIndex : 0,
          isShowVertifyCode: false,
          timersecond : 60,
          isShowPromptInfo: false,
          promptInfo : 'none',
          promptTimer:null
        };
      },
      computed: {
        ...mapState({
          vertifyCode: state => state.auth.vertifyCode
        })
      },
      components: { NavHeader },
      mounted(){
        if(this.vertifyCode === null || this.vertifyCode === 'undefined' || !this.vertifyCode ){
          this.$router.push('/login');
        }
    
        // 此页面是login跳转页面,在login页面中已经实现了短信码的发送
        // 所以在此页面中进入后就默认到第一个输入框
        let vertifyInputArray = this.$refs.vertifyWrapper.getElementsByClassName(
            "login_input"
          );
          vertifyInputArray[0].focus();
    
          this.setTimersecond();
    
        console.log(this.vertifyCode);
      },
      methods:{
        showPromptInfo(msg){
          this.isShowPromptInfo = true;
          this.promptInfo = msg;
    
          this.promptTimer = setTimeout(()=>{
            this.isShowPromptInfo = false;
          }, 2000);
        },
        setTimersecond(){
          this.timersecond = 60;
          var timer = setInterval(()=>{
            this.timersecond--;
            if(this.timersecond ===0 ){
              clearInterval(timer);
              this.isShowVertifyCode = true;
            }
          }, 1000)
        },
        getVertifycode(){
          var dataMobile = { mobile: this.vertifyCode.mobile };
          
          this.$axios
            .post("/api/auth/loginvertifycode", dataMobile)
            .then(res => {
              console.log(res.data);
    
              let _data = res.data;
              let _smsid = _data.smsid;
    
              console.log(_smsid);
    
              if(_smsid !== ''){
                const sms = {mobile:_data.mobile, smsid:_smsid};
    
                this.$store.commit('setVertifyCode', sms);
    
                let vertifyInputArray = this.$refs.vertifyWrapper.getElementsByClassName(
                  "login_input"
                );
    
                for(let n1=0; n1<vertifyInputArray.length; n1++){
                  vertifyInputArray[n1].value = '';
                }
    
                vertifyInputArray[0].focus();
    
                this.setTimersecond();
              }
            })
            .catch(err => {
              console.log(err);
            });
        },
        clearInput(event){
          if(event.srcElement.value.toString().length >= 1){
            event.srcElement.value = '';
          }
        },
        goVertify(event){
          let vertifyInputArray = this.$refs.vertifyWrapper.getElementsByClassName(
            "login_input"
          );
    
          for(let n1=0; n1<vertifyInputArray.length; n1++){
            if(event.srcElement === vertifyInputArray[n1]){
              this.inputVertifyCode[n1] = vertifyInputArray[n1].value;
    
              if(n1 === vertifyInputArray.length -1 ){
                this.doGovertify();
              }
              else{
                if( vertifyInputArray[n1].value !== '' ){
                  vertifyInputArray[n1+1].focus();
                }
              }
            }
          }
          console.log(this.inputVertifyCode)
        },
        doGovertify(){
          const smscode = this.inputVertifyCode.join('');
          const smsauth = {
            mobile: this.vertifyCode.mobile,
            smsid: this.vertifyCode.smsid,
            smscode: smscode
          };
          console.log(smsauth);
          this.$axios.post("/api/auth/vertify", {smsauth}).then(res=>{
            console.log(res.data);
    
            const rtndata = res.data;
    
            if(rtndata.code === 'ERROR'){
                this.showPromptInfo(rtndata.message);
            }else if(rtndata.code === 'SUCCESS'){
              this.$router.replace("/me");
            }
            
          }).catch(err => {
              console.log(err);
            });
        }
        
      }
    };
    </script>
    
    <style lang="scss" scoped>
    .vertifycodeIcon {
      color: #e2041b !important;
      width: 2.5rem !important;
      height: 2.5rem !important;
    }
    .login_input {
      padding-top: 14px;
      padding-bottom: 14px;
      margin-right:8px;
      height: 54px;
      width: 45px;
      padding-left: 18px;
      color: #262626;
      font-size: 16px;
      border-radius: 0.5rem;
      box-sizing: border-box;
      line-height: 1;
      border: solid 1px #f3f3f3;
      outline:none;
      background-color: #f3f3f3 !important;
    }
    .login_input:focus{
      border: solid 1px #e60033;
    }
    
    .InfoWrapper{
      position: absolute;
      flex-direction: column;
      width: 100%;
      height: 100%;
      top: 0px;
      left:0px;
      z-index:50;
      -webkit-transform: translateZ(0);
        transform: translateZ(0);
    }
    .mainWrapper{
      margin: 0px 50px 0px 50px;
      padding: 18px 16px 16px 16px;
      text-align:center;
      background-color: #1a202c;
      opacity: 0.9;
      color: #fff;
      font-size:14px;
      border-radius: 0.75rem;
    
    }
    .infoIcon {
      color: #fff !important;
      width: 2.5rem !important;
      height: 2.5rem !important;
    }
    </style>
    

    其他

    1、此代码在一些环节都还需要优化,但目前主要功能都已经实现,希望对大家能有帮助。

    相关文章

      网友评论

        本文标题:【经验分享】VUE中短信验证码六位数字框输入设计

        本文链接:https://www.haomeiwen.com/subject/kmfcpktx.html