Vue项目之登录注册


Vue项目之登录注册

1.1 注册页面的布局

需要用到Vant的Field组件
1.views下新建一个注册页面 ,完成基本布局。引入Vue和Field并使用。
2.在官方文档中搜索,查看自己需要的内容,将其直接粘贴到页面中。
3.给注册页面添加一个单独的路由,注册页面不需要底部。(注意,相关样式需要引入不同的组件,请细心查看官方文档,按需拿取内容)
4. 利用计算属性给输入框做条件判断。本案例以手机号为例。

 

  

<template>
<div class="container">
<header class="header">注册</header>
<div class="content">
<van-field
v-model="username"
placeholder="请输入手机号"
clearable
:error-message="usernamemsg"
/>
<van-field
v-model="password"
type="password"
clearable
placeholder="请输入密码"
error-message="密码格式错误"
/>
<van-field
v-model="code"
center
clearable
placeholder="请输入短信验证码"
error-message="验证码格式错误"
>
<van-button slot="button" size="small" type="primary">发送验证码</van-button>
</van-field>
</div>
</div>
</template>

<script>
import Vue from 'vue'
import { Field, Button } from 'vant'

Vue.use(Field)
Vue.use(Button)
export default {
data () {
return {
username: '18813007814',
password: '123456',
code: ''
}
},
computed: {
usernamemsg () {
if (this.username === '') {
return ''
} else if (!/^[1][3,4,5,7,8][0-9]{9}$/.test(this.username)) {
return '手机号码格式错误'
} else {
return ''
}
}
}
}
</script>

 

 

 

1.2 注册业务逻辑的实现

注:在此之前,记住要先去路由页面添加一个注册页面的路由。
1.补充了密码以及验证码的计算属性判断
密码:如果为空返回空,如果不符合正则,返回格式错误,否则表示可以直接返回空
验证码:如果为空返回空,否则不为五位,返回验证码格式错误,否则成功返回空

2.验证码

  • 绑定点击事件senCode
  • 将提示信息{{buttonmsg}}放在按钮内容中。
  • 定义函数:(定时器注意用箭头函数)每一秒钟定义一次,先提前声明时间,在计时器内让时间减减,当时间为零时,清除定时器,同时btn的内容改为发送验证码,最后return。未return时,让按钮内的内容为时间减减+后重新发送(注意:在开启定时器时,要让按钮禁止点击,在清除定时器后再让按钮可点。)

3.验证码跟接口做交互
在setCode最后定义一个getCode函数,在下方定义该函数(类似面向对象写法)。
定义getCode:

  • 需要引入Toast并使用,请提示
  • 在该函数中也可以去验证手机号是否正确,不正确显示相关提示信息
  • 否则正确,就去axios去post请求数据,然后打印数据,去判断返回信息,跟接口文档相对应,如果为1则是用户名已经注册,0为获取验证码失败,成功在data里再定义adminCode用来存放验证码,通过res.data.code可以获取,加入该值中。

4.引入一个按钮,作为注册按钮
定义register函数
1.判断:

  • 将手机号的验证再写一遍,如果不符合,则toast提示,直接return
  • 验证密码,不符合同样提示并return
  • 验证码验证,不符合toast提示,并return

2.当上面的判断都通过,再定义真正的注册函数

    • 调接口,修改注册按钮为不可点,并修改值为注册中,在注册按钮写上:loading=“loading” loading-text=“注册中” disabled=“flag”
    • this.flag=true,this.loading=true
    • axios的post请求数据,第二个参数为用户手机号和密码。请求成功后先去更改按钮的状态,this.flag,this.loading都改为false。 再去判断返回值(根据接口文档定义) 2->用户名已经注册,0->注册失败,否则注册成功
      5.在注册页面增加登录按钮,用来做跳转。
      记住不能用声明式跳转,用编程式跳转,用replace跳转到另一个页面(返回直接回到个人中心)
    • <template>
    • <div class="container">
      <header class="header">注册头部</header>
      <div class="content">
      <van-field
      v-model="tel"
      placeholder="请输入手机号"
      :error-message="usertel"

      clearable
      />
      <van-field
      v-model="password"
      type="password"
      placeholder="请输入密码"
      :error-message="pass"

      clearable
      />
      <van-field
      v-model="sms"
      center
      clearable
      placeholder="请输入短信验证码"
      :error-message="test"
      >
      <van-button :disabled="flag" slot="button" size="small" type="primary" @click="sendCode">{{ buttonmsg }}</van-button>

      </van-field>
      <van-button type="primary" :loading="loading" loading-text="注册..." size="large" :disabled="zhud" @click="register">注册</van-button>
      <van-divider @click="toLogin">去登录</van-divider>
      </div>
      </div>
      </template>
      <script>
      import Vue from 'vue'
      import { Field,Button,Toast,Divider } from 'vant'
      import axios from 'axios'
      Vue.use(Field)
      Vue.use(Button)
      Vue.use(Toast)
      Vue.use(Divider)

      export default {
      data () {
      return {
      tel:'',
      password:'',
      sms:'',
      buttonmsg:'点击发送验证码',
      flag:false,
      adminCode:'',
      zhud:false,
      loading:false
      }
      },
      computed: {
      usertel () {
      if (this.tel === ""){
      return ''
      }else if(!/^[1][3,4,5,7,8][0-9]{9}$/.test(this.tel)){
      return '手机号格式错误'
      }else {
      return ''
      }
      },
      pass () {
      if (this.password === ""){
      return ''
      }else if(this.password.length<6){
      return '密码不可小于6位'
      }else {
      return ''
      }
      },
      test () {
      if (this.sms === ""){
      return ''
      }else if(this.sms.length !== 5){
      return '验证码格式错误'
      }else {
      return ''
      }
      }
      },
      methods: {
      toLogin () {
      this.$router.replace('/login')
      },
      sendCode () {
      let time = 4
      let timer
      timer = setInterval(()=>{
      time --
      if(time === 0){
      clearInterval(timer)
      this.flag=false
      this.buttonmsg = '点击发送验证码'
      return
      }
      this.flag = true
      this.buttonmsg = time + '秒后重新发送'

      },1000)
      this.getCode()
      },
      getCode () {
      if(!/^[1][3,4,5,7,8][0-9]{9}$/.test(this.tel) || this.tel===""){
      Toast('手机号码输入有误')
      }else{
      axios.get('https://www.daxunxun.com/users/sendCode?tel='+this.tel).then(res=>{
      if(res.data === 1){
      Toast('用户名已注册,请更改')
      }else if(res.data === 0){
      Toast('获取验证码失败')
      }else{
      this.adminCode = res.data.code
      console.log(this.adminCode)
      }
      })
      }
      },
      register () {
      if (this.tel === '' || this.usertel === '手机号码格式错误') {
      Toast('手机号码输入有误')
      return
      }
      if (this.password === '' || this.pass === '密码格式错误,最少为6位') {
      Toast('密码输入有误')
      return
      }
      if (this.sms === '' || this.sms !== this.adminCode) {
      Toast('验证码输入有误')
      return
      }
      this.reallR()
      },
      reallR () {
      this.zhud=true
      this.loading=true
      axios.post('https://www.daxunxun.com/users/register', {
      username: this.tel,
      password: this.password
      }).then(res=>{
      this.zhud=false
      this.loading=false
      if (res.data === 2) {
      Toast('用户名已注册,请直接登录')
      } else if (res.data === 0) {
      Toast('注册失败')
      } else {
      Toast('注册成功')
      }
      })
      }
      }
      }
      </script>

    • 2. 登录

      页面布局以及基本逻辑同注册基本相同,可直接复制注册,将相关注册字样更改为登录。删除相关的判断。更改相关函数。

    • <template>
      <div class="container">
      <header class="header">注册头部</header>
      <div class="content">
      <van-field
      v-model="tel"
      placeholder="请输入手机号"
      :error-message="usertel"

      clearable
      />
      <van-field
      v-model="password"
      type="password"
      placeholder="请输入密码"
      :error-message="pass"

      clearable
      />
      <van-button type="primary" :loading="loading" loading-text="登录..." size="large" :disabled="zhud" @click="login">登录</van-button>
      <van-divider @click="toRegister">去注册</van-divider>
      </div>
      </div>
      </template>
      <script>
      import Vue from 'vue'
      import { Field,Button,Toast,Divider} from 'vant'
      import axios from 'axios'
      // import { setInterval, clearInterval } from 'timers';
      // import func from '../../../vue-temp/vue-editor-bridge';
      Vue.use(Field)
      Vue.use(Button)
      Vue.use(Toast)
      Vue.use(Divider)

      export default {
      data () {
      return {
      tel:'',
      password:'',
      zhud:false,
      loading:false
      }
      },
      computed: {
      usertel () {
      if (this.tel === ""){
      return ''
      }else if(!/^[1][3,4,5,7,8][0-9]{9}$/.test(this.tel)){
      return '手机号格式错误'
      }else {
      return ''
      }
      },
      pass () {
      if (this.password === ""){
      return ''
      }else if(this.password.length<6){
      return '密码不可小于6位'
      }else {
      return ''
      }
      }
      },
      methods: {
      toRegister () {
      this.$router.replace('/register')
      },
      login () {
      if (this.tel === '' || this.usertel === '手机号码格式错误') {
      Toast('手机号码输入有误')
      return
      }
      if (this.password === '' || this.pass === '密码格式错误,最少为6位') {
      Toast('密码输入有误')
      return
      }
      if (this.sms === '' || this.sms !== this.adminCode) {
      Toast('验证码输入有误')
      return
      }
      this.reallR()
      },
      reallR () {
      this.zhud=true
      this.loading=true
      axios.post('https://www.daxunxun.com/users/login', {
      username: this.tel,
      password: this.password
      }).then(res=>{
      this.zhud=false
      this.loading=false
      if (res.data === 2) {
      Toast('用户未注册')
      } else if(res.data === -1){
      Toast('密码错误')
      }else if (res.data === 0) {
      Toast('登录失败')
      } else {
      Toast('登录成功')
      localStorage.setItem('isLogin','ok') //登录标识
      this.$router.back() //登陆成功返回上一页
      }
      })
      }
      }
      }
      </script>

      • 3.导航守卫

        3.1全局导航守卫,全部路由都会经过这里。一定要调用next方法向下执行

        除了登陆路由,其他页面都需要登录验证。

    • router.beforeEach((to,from,next)=>{
      // console.log(to)
      // console.log(from)
      // next() //至此就可以显示页面了
      //做业务逻辑,如果是登录状态,就进行下一步(注意登录页面不可做这个判断)
      if(to.name = 'login'){ //如果要去的页面是登录页面,就进行下一步,不做判断
      next()
      }else{
      if(localStorage.getItem('isLogin')==='ok'){
      next()
      }else{
      next('/login')
      }
      }

    • 3.2 路由独享的导航守卫

      路由独享的导航守卫—一般不推荐直接使用
      比如在购物车路由下方加入下面一段代码,可以实现购物车页面的相关判断。
      没有登录状态就直接去到登录页面,有登录状态就继续下一步。

    • beforeEnter (to,from,next) {
      if(localStorage.getItem('isLogin')==="ok"){
      next()
      }else{
      next('/login')
      }
      }

    • 3.3 组件内的导航守卫

      先来简单看一下组件内的导航守卫相关介绍:

    • const Foo = {
      template: `...`,
      beforeRouteEnter (to, from, next) {
      // 在渲染该组件的对应路由被 confirm 前调用
      // 不!能!获取组件实例 `this`
      // 因为当守卫执行前,组件实例还没被创建
      },
      beforeRouteUpdate (to, from, next) {
      // 在当前路由改变,但是该组件被复用时调用
      // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
      // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
      // 可以访问组件实例 `this`
      },
      beforeRouteLeave (to, from, next) {
      // 导航离开该组件的对应路由时调用
      // 可以访问组件实例 `this`
      }
      }

    • beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。

      不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

    • beforeRouteEnter (to, from, next) {
      next(vm => {
      // 通过 `vm` 访问组件实例
      })
      }

    • 本文以购物车页面为例,在路由进入之前,做一个判断,有登录状态进行下一步,没有登录状态就直接去到登录页面。组件内的导航守卫有两张写法,请看案例,且不同写法有不同的效果,按需而定
    • <template>
      <div class="container">
      <header class="header">购物车头部</header>
      <div class="content">购物车内容</div>
      </div>
      </template>
      <script>
      export default {
      beforeRouteEnter (to,from,next) {
      // if (localStorage.getItem('isLogin')==='ok'){
      // next()
      // }else{
      // next('/login') //这种登陆成功返回点击购物车之前的页面
      // }
      next(vm => {
      if (localStorage.getItem('isLogin')==='ok'){
      next()
      }else{
      // next('./login')
      vm.$router.push('/login') //这种登录成功直接返回到了购物车
      }
      })
      }
      }
      </script>


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM