vue_登录注册(前台验证)

 

一、前言                                                                            

                                1、切换手机登录还是密码登录

                                2、显示发送验证码

                                3、点击发送验证码显示“已发送()”

                                4、密码框的内容显示隐藏效果

                                5、提交表单进行前台验证,出现不正确给出提示

 

 

二、主要内容                                                                     

1、切换手机登录还是密码登录

      (1)手机选择切换的时候先看看有哪些变化,是什么导致了变化(当前的都多加了一个类)

      (2)手机登录和密码登录是互斥的,用一个属性来标识,

data(){
      return {
        loginWay:true//true为短信登录,false为密码登录
      }
   }

       (3)点击“短信登录”的时候直接将当前的标识置为true, 点击“密码登录”的时候将当前标识置为false, 

               如果这个标识为true就给“短信登录”加上类名on,

               如果这个标识为false就给“密码登录”加上类名on, 

 <a href="javascript:;" :class="{on:loginWay}" @click="loginWay=true">短信登录</a>
 <a href="javascript:;" :class="{on:loginWay==false}" @click="loginWay=false">密码登录</a>

       (4)点击切换的时候,下面的表单提交框也要切换到相应的(这里通常是控制当前提交框的显示隐藏)

<!--短信登录:这个on是控制当前提交框显示隐藏的, 如果true就显示短信登录提交框-->
<div :class="{on:loginWay}">
.....短信登录
</div>

<!--密码登录:这个on是控制当前提交框显示隐藏的, 如果false就显示密码提交框-->
<div :class="{on:loginWay}">
...密码登录
</div>

 

2、显示发送验证码

    (1)效果,最开始“获取验证码”这几个字是灰色的,当匹配到输入的是11位数字的时候就会变为黑色

    (2)首先要给文本框双向绑定数据,因为“获取验证码”的字体颜色是和前面输入的内容有关的,所有我们可以用computed来监听前面的数字,当达到某个状态的时候就可以自动添加上那个文字的类名

      第一步:v-model

 
<!--后面的字体颜色和输入框有关,就可以用计算属性监听    right_number是正确匹配后添加的字体颜色类-->
<input type="tel" maxlength="11" placeholder="手机号" v-model="phone">
<button disabled="disabled" class="get_verification" :class="{right_number:Cphone }">获取验证码</button>

    第二步:

 data(){
      return {
        loginWay:true,//true为短信登录,false为密码登录
        phone:''
      }
     },
     computed:{
      Cphone(){
        return /^1\d{10}$/.test(this.phone)
      }
     }

 

 

3、点击发送验证码显示“已发送()”

   (1)点击“发送验证码”的时候才显示“已发送(s)”,当这个时间不为0的时候显示“已发送”,为0的时候显示“点击获取验证码”,所以现在需要一个属性,并且监听该属性

 <!--获取验证码这个按钮默认是被禁用的,当匹配正确之后才能点击-->
<!--如果不阻止默认事件,点击按钮的时候会提交一次表单,-->
<button :disabled="!Cphone" class="get_verification" :class="{right_number:Cphone }" @click.prevent="getCode()" v-text="computedTime>0?`已发送(${computedTime}s)`:'获取验证码'"></button>

   (2)在method中定义那个方法,获取到当前的computedTime, 并且用一个定时器

 data(){
      return {
        computedTime:0 //标识
      }
     },
    
     methods:{
      getCode(){
        
        //点击已发送,当正在已发送的时候不需要再启动定时器
        if(this.computedTime==0){
          this.computedTime=30
          var IntervalId=setInterval(()=>{
          this.computedTime--
          if(this.computedTime<=0){
            clearInterval(IntervalId) //关闭定时器
          }
        },1000)
        }
      }

 

4、密码框的内容显示隐藏效果

    (1)显示效果如图

 

    (2)这里其实是有两个input密码输入框,如果type="text"显示的就是文本,如果type="password"显示的就是点点点

 <!--然后用v-if根据标识来设置到底此时的状态是显示还是隐藏-->

<input type="text" maxlength="8" placeholder="密码" v-if="showPwd" v-model='pwd'>
<input type="password" maxlength="8" placeholder="密码" v-else v-model='pwd'>

    (3)在data中定义标识,然后看看右边的按钮,其实有三个地方改变(①点击时背景颜色改变, ②点击时小球球从左边滑到了右边,③点击后文字显示和切换)

 data(){
      return {
  
        pwd:'',//密码
        showPwd:true //标识是否显示,true显示文本, false显示点点
       }
     },

    (4)控制小球显示

 <!--点击的时候改变showPwd的值从而显示文本还是点点点-->
 <!--on /off是改变背景颜色的,如果为true有背景颜色-->
 <!--right是改变小球球从左到右的,-->
<div class="switch_button " :class="showPwd?'on':'off'"  @click="showPwd=!showPwd">
                    <div class="switch_circle" :class="{right: showPwd}"></div>
                    <span class="switch_text">{{showPwd? 'abc': '...'}}</span>
                  </div>

 

5、提交表单进行前台验证,出现不正确给出提示

    (1)效果

    (2)先收集验证的信息(所有的input框),并且给每个收集的信息v-model

 data(){
      return {
        loginWay:true,//true为短信登录,false为密码登录
        phone:'', //收集号码
        pwd:'',//密码
        code:'',//短信验证码
        name:'', //验证用户名
        captche:'',//图片验证码
        alertText:'',//提示文本
        showAlert:false //是否显示提示框
      }
     },

   (2)将提示框提取为复用组件,并且在登录组件中引入

<template>
  <div class="alert_container">
    <section class="tip_text_container">
      <div class="tip_icon">
        <span></span>
        <span></span>
      </div>
      <p class="tip_text">{{alertText}}</p>
      <div class="confrim" @click="closeTip">确认</div>
    </section>
  </div>
</template>

<script>
  export default {
    props: {
      alertText: String
    },

    methods: {
      closeTip() {
        // 分发自定义事件(事件名: closeTip)
        this.$emit('closeTip')
      }
    }
  }
</script>

<style lang="stylus" rel="stylesheet/stylus" scoped>
  @import '../../common/stylus/mixins.styl';

  @keyframes tipMove
    0%
      transform: scale(1)
    35%
      transform: scale(.8)
    70%
      transform: scale(1.1)
    100%
      transform: scale(1)

  .alert_container
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 200;
    background: rgba(0, 0, 0, .5)
    .tip_text_container
      position: absolute;
      top: 50%;
      left: 50%;
      margin-top: -90px
      margin-left: -110px
      width: 60%
      animation: tipMove .4s;
      background-color: rgba(255, 255, 255, 1);
      border: 1px;
      padding-top: 20px
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      border-radius: 5px
      .tip_icon
        width: 55px
        height: 55px
        border: 2px solid #f8cb86;
        border-radius: 50%;
        font-size 20px
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
        span:nth-of-type(1)
          width: 2px
          height: 30px
          background-color: #f8cb86;
        span:nth-of-type(2)
          width: 2px
          height: 2px
          border: 1px;
          border-radius: 50%;
          margin-top: 2px
          background-color #f8cb86
      .tip_text
        font-size 14px
        color #333
        line-height 20px
        text-align center
        margin-top 10px
        padding 0 5px
      .confrim
        font-size 18px
        font-weight bold
        margin-top 10px
        background-color #4cd964
        width 100%
        text-align center
        line-height 35px
        border 1px
        color #fff
        border-bottom-left-radius 5px
        border-bottom-right-radius 5px
</style>
提示框.vue
//1.引入
  import AlertTip from '../../components/AlterTip/AlterTip'
//2.挂载
components:{
       AlertTip
     }

使用:

<!--这里绑定了alertText用来显示当前提示的文本信息-->
<!--showAlert:用来确定是否需要显示这个提示框,如果showAlert=true显示, 默认不显示-->
 <AlertTip :alertText='alertText' v-show="showAlert" @closeTip="closeTip()"></AlertTip>

 

 (3)给from表单添加提交验证事件,并且不要跳转

<!--提交表单-->
<form @submit.prevent="Login()">
<form>

  (4)在method里面定义好验证方法,这个表单验证分为两部分,短信登录验证和密码登录验证,接下来主要是处理alertText,showAlert

    //表单验证
      Alertshow(alertText){
        this.showAlert=true; //显示
        this.alertText=alertText
      },
     
      Login(){
         //一上来先区别登录方式
         if(this.loginWay){//短信登录
           const {Cphone, phone, code} = this
           if(!this.Cphone){
            //手机号不正确
            this.Alertshow('手机号不正确')

           }else if(/^\d{6}$/.test(code)){
            //短信验证码必须为六位的数字
            this.Alertshow('短信验证码必须为六位的数字')

           }


         }else{//密码登录
            const {name, pwd, captche }=this
             if(!this.name){
            //用户名必须有
             this.Alertshow('用户名必须有')

           }else if(!this.pwd){
            //密码必须输
            this.Alertshow('密码必须输')

           }else if(!this.captche){
            //验证码必须有
             this.Alertshow('验证码必须有')
           }

         }
      },

 

   (5)点击提示框的“确定”按钮,隐藏提示框,并且清空文字

           这里用到了父子组件之间通信的方式

           第一步:在父组件中定义一个自定义事件

 <!--@closeTip父组件中定义-->
<AlertTip :alertText='alertText' v-show="showAlert" @closeTip="closeTip()"></AlertTip>

           第二步:子组件中定义一个原生的cllick事件

<!--这里定义了一个原生click事件-->
<div class="confrim" @click="closeTip">确认</div>
<script>
  export default {
    props: {
      alertText: String
    },

    methods: {
      closeTip() {
        // 分发自定义事件(事件名: closeTip),来触发父组件中的自定义事件
        this.$emit('closeTip')
      }
    }
  }
</script>

      第三步:点击子组件中的确定按钮时,父组件中就会执行这个closeTip事件

 closeTip(){
        this.showAlert=false //隐藏
        this.alertText=''
        console.log(1111);

      }

 

 

 

 

 

三、总结                                                                            

 

<template>
   <section class="loginContainer">
      <div class="loginInner">
        <div class="login_header">
          <h2 class="login_logo">硅谷外卖</h2>
          <div class="login_header_title">
            <a href="javascript:;" :class="{on:loginWay}" @click="loginWay=true">短信登录</a>
            <a href="javascript:;" :class="{on:loginWay==false}" @click="loginWay=false">密码登录</a>
          </div>
        </div>
        <div class="login_content">
          <form @submit.prevent="Login()">
            <div :class="{on:loginWay}">
              <section class="login_message">
                <input type="tel" maxlength="11" placeholder="手机号" v-model="phone">
                <button :disabled="!Cphone" class="get_verification" :class="{right_number:Cphone }" @click.prevent="getCode()" v-text="computedTime>0?`已发送(${computedTime}s)`:'获取验证码'" v-model="code"></button>
              </section>
              <section class="login_verification">
                <input type="tel" maxlength="8" placeholder="验证码">
              </section>
              <section class="login_hint">
                温馨提示:未注册硅谷外卖帐号的手机号,登录时将自动注册,且代表已同意
                <a href="javascript:;">《用户服务协议》</a>
              </section>
            </div>
            <div :class="{on:loginWay==false}">
              <section>
                <section class="login_message">
                  <input type="tel" maxlength="11" placeholder="手机/邮箱/用户名" v-model="name">
                </section>
                <section class="login_verification">
                  <input type="text" maxlength="8" placeholder="密码" v-if="showPwd" v-model='pwd'>
                  <input type="password" maxlength="8" placeholder="密码" v-else v-model='pwd'>
                  <div class="switch_button " :class="showPwd?'on':'off'"  @click="showPwd=!showPwd">
                    <div class="switch_circle" :class="{right: showPwd}"></div>
                    <span class="switch_text">{{showPwd? 'abc': '...'}}</span>
                  </div>
                </section>
                <section class="login_message">
                  <input type="text" maxlength="11" placeholder="验证码" v-model="captche">
                  <img class="get_verification" src="./images/captcha.svg" alt="captcha">
                </section>
              </section>
            </div>
            <button class="login_submit">登录</button>
          </form>
          <a href="javascript:;" class="about_us">关于我们</a>
        </div>
        <a href="javascript:" class="go_back">
          <i class="iconfont icon-icon-arrow-left" @click="$router.back()"></i>
        </a>
      </div>


      <AlertTip :alertText='alertText' v-show="showAlert" @closeTip="closeTip()"></AlertTip>
    </section>
    

</template>
<script type="text/javascript">
  import AlertTip from '../../components/AlterTip/AlterTip'
    export default{
     data(){
      return {
        loginWay:true,//true为短信登录,false为密码登录
        phone:'',
        computedTime:0,
        pwd:'',//密码
        showPwd:true ,//标识是否显示,true显示文本, false显示点点
        code:'',//短信验证码
        name:'',
        captche:'',//图片验证码
        alertText:'',//提示文本
        showAlert:false //是否显示提示框
      }
     },
     components:{
       AlertTip
     },
     computed:{
      Cphone(){
        return /^1\d{10}$/.test(this.phone)
      }
     },
     methods:{
      getCode(){
        
        //点击已发送,当正在已发送的时候不需要再启动定时器
        if(this.computedTime==0){
          this.computedTime=30
          var IntervalId=setInterval(()=>{
          this.computedTime--
          if(this.computedTime<=0){
            clearInterval(IntervalId)
          }
        },1000)
        }
      },
      //表单验证
      Alertshow(alertText){
        this.showAlert=true; //显示
        this.alertText=alertText
      },
     
      Login(){
         //一上来先区别登录方式
         if(this.loginWay){//短信登录
           const {Cphone, phone, code} = this
           if(!this.Cphone){
            //手机号不正确
            this.Alertshow('手机号不正确')

           }else if(/^\d{6}$/.test(code)){
            //短信验证码必须为六位的数字
            this.Alertshow('短信验证码必须为六位的数字')

           }


         }else{//密码登录
            const {name, pwd, captche }=this
             if(!this.name){
            //用户名必须有
             this.Alertshow('用户名必须有')

           }else if(!this.pwd){
            //密码必须输
            this.Alertshow('密码必须输')

           }else if(!this.captche){
            //验证码必须有
             this.Alertshow('验证码必须有')
           }

         }
      },

      closeTip(){
        this.showAlert=false //隐藏
        this.alertText=''
        console.log(1111);

      }
     }
    }
</script>

<style lang="stylus" rel="stylesheet/stylus">
  @import "../../common/stylus/mixins.styl"
    .loginContainer
      width 100%
      height 100%
      background #fff
      .loginInner
        padding-top 60px
        width 80%
        margin 0 auto
        .login_header
          .login_logo
            font-size 40px
            font-weight bold
            color #02a774
            text-align center
          .login_header_title
            padding-top 40px
            text-align center
            >a
              color #333
              font-size 14px
              padding-bottom 4px
              &:first-child
                margin-right 40px
              &.on
                color #02a774
                font-weight 700
                border-bottom 2px solid #02a774
        .login_content
          >form
            >div
              display none
              &.on
                display block
              input
                width 100%
                height 100%
                padding-left 10px
                box-sizing border-box
                border 1px solid #ddd
                border-radius 4px
                outline 0
                font 400 14px Arial
                &:focus
                  border 1px solid #02a774
              .login_message
                position relative
                margin-top 16px
                height 48px
                font-size 14px
                background #fff
                .get_verification
                  position absolute
                  top 50%
                  right 10px
                  transform translateY(-50%)
                  border 0
                  color #ccc
                  font-size 14px
                  background transparent
                  &.right_number
                    color: black
              .login_verification
                position relative
                margin-top 16px
                height 48px
                font-size 14px
                background #fff
                .switch_button
                  font-size 12px
                  border 1px solid #ddd
                  border-radius 8px
                  transition background-color .3s,border-color .3s
                  padding 0 6px
                  width 30px
                  height 16px
                  line-height 16px
                  color #fff
                  position absolute
                  top 50%
                  right 10px
                  transform translateY(-50%)
                  &.off
                    background #fff
                    .switch_text
                      float right
                      color #ddd
                  &.on
                    background #02a774
                  >.switch_circle
                    //transform translateX(27px)
                    position absolute
                    top -1px
                    left -1px
                    width 16px
                    height 16px
                    border 1px solid #ddd
                    border-radius 50%
                    background #fff
                    box-shadow 0 2px 4px 0 rgba(0,0,0,.1)
                    transition transform .3s
                    &.right
                      transform translateX(30px)
              .login_hint
                margin-top 12px
                color #999
                font-size 14px
                line-height 20px
                >a
                  color #02a774
            .login_submit
              display block
              width 100%
              height 42px
              margin-top 30px
              border-radius 4px
              background #4cd96f
              color #fff
              text-align center
              font-size 16px
              line-height 42px
              border 0
          .about_us
            display block
            font-size 12px
            margin-top 20px
            text-align center
            color #999
        .go_back
          position absolute
          top 5px
          left 5px
          width 30px
          height 30px
          >.iconfont
            font-size 20px
            color #999
</style>
Login.vue

 

posted @ 2019-05-06 21:26  mysunshine_SZZ  阅读(4615)  评论(0编辑  收藏  举报