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>
//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>