1、前言 javascript
一、切換手機登陸仍是密碼登陸vue
二、顯示發送驗證碼java
三、點擊發送驗證碼顯示「已發送()」ide
四、密碼框的內容顯示隱藏效果svg
五、提交表單進行前臺驗證,出現不正確給出提示字體
2、主要內容 flex
一、切換手機登陸仍是密碼登陸this
(1)手機選擇切換的時候先看看有哪些變化,是什麼致使了變化(當前的都多加了一個類)spa
(2)手機登陸和密碼登陸是互斥的,用一個屬性來標識,3d
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>
二、顯示發送驗證碼
(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) } }
三、點擊發送驗證碼顯示「已發送()」
(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) } }
四、密碼框的內容顯示隱藏效果
(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>
五、提交表單進行前臺驗證,出現不正確給出提示
(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); }
3、總結
<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>