电商前台项目(六)完结撒花:完成注册登录功能、路由守卫

一、完成注册部分

在这里插入图片描述

(1)获取验证码完成注册

首先把登录注册的静态页面搞过来,然后实现验证码部分,这里就是单纯的模拟一下,输入手机号,发送请求获取一个验证码,然后直接展示在文本框里,比较简单,就不多说了。

1.接口:
//10.获取验证码的接口
// /api/user/passport/sendCode/{phone}
export const reqRegisterCode = function(phone) {
    return requests.get(`/user/passport/sendCode/${phone}`);
}

2.vuex:
async getRegisterCode({commit}, phone) {
        try{
            let result = await reqRegisterCode(phone);
            commit('GETREGISTERCODE', result.data);
        }catch(err) {
            console.log(err.message);
        }
    },
    
3.双向绑定手机号,点击验证码按钮派发请求
getRegisterCode() {
     //来个逻辑短路
     this.phone && this.$store.dispatch('login/getRegisterCode', this.phone);
   },

(2)完成注册用户业务

这部分也比较简单,主要是拿着手机号、验证码、密码去发送请求,添加到数据库。

1.接口
//11.注册用户的接口
// /api/user/passport/register
export const reqRegisterUser = (phone, password, code) => {
    return requests({
        method: 'post',
        url: '/user/passport/register',
        data: {
            phone,
            password,
            code
        }
    })
}
2.vuex
async sendRegisterUser(context,{ phone, password, code}) {
        console.log(context);
        try {
            let result = await reqRegisterUser(phone, password, code);
            console.log(result);
            if(result.code == 200) {
                return '注册成功';
            }
            if(result.code == 223) {
                return '该用户已注册!'
            }
        }catch(err) {
            alert('请求失败',err.message);
        }   
    }
3.点击注册按钮派发请求
data() {
  return {
    phone: '', //手机号
    password: '', //密码
    passwordConfirm: '', //确认密码
    agree: false, //是否同意
  }
},

.......

async completeRegister() {
 try {
    //来个逻辑短路
    const {phone, password, passwordConfirm, agree, registerCode} = this;
    if(phone&&registerCode&&password&&passwordConfirm&&password==passwordConfirm&&agree==true) {
      let result = await this.$store.dispatch('login/sendRegisterUser', {phone, code:registerCode, password})
      alert(result);
      if(result == '注册成功') {
        this.$router.push({
          name: 'denglu'
        })
      }
    }
  }catch(err) {
    alert('注册失败!',err)
  }
},

二、登录

在这里插入图片描述

click.prevent阻止默认提交表单的操作,避免跳来跳去。复习阻止事件默认行为入口

(1)点击登录发送请求校验

然后写登录接口,点击登录时拿着用户名密码发请求校验:

1.接口
//12.登录接口
// /api/user/passport/login
export const reqUser = (phone, password) => {
    return requests({
        url: 'user/passport/login',
        method: 'post',
        data: {phone,password}
    })
}

2.vuex
//2.登录
async userLogin(context, {phone,password}) {
    let result = await reqUser(phone, password);
    console.log('登录请求成功',result);
}

3.派发请求,路由跳转
userLogin() {
 try {
    let {phone,password} = this;
    (phone&&password)&&this.$store.dispatch('login/userLogin',{phone, password});
    this.$router.push('/home');
  }catch(err) {
    alert('登录请求失败!',err.message);
  }
}

请求数据后,服务端会返回一个字段,名字叫token

(2)保存下发的token

当我们点击登录,返回的数据是这样的,里面有一个字段叫token,它就是用户的唯一标识,将来我们请求用户相关的东西就要拿着这个token
由于vuex是非持久性存储数据,一刷新就没了,所以我们要把token放在本地存储中

在这里插入图片描述
后面的每个请求都要和token有关,所以我们要把token写到请求头中

在这里插入图片描述

(3)拿着token请求用户数据并展示

这里有个问题,就是这个请求的派发应该写在哪里

1、如果只在home页写,那么跳转到其他页面点击刷新vuex中的用户数据就没了;但是如果每个用到用户名的组件都要派发,那就太麻烦了。
2、如果在app写,那么派发请求是在登录前,还没有token呢就请求不到数据,只有登录之后刷新页面(已经有token)才能请求到(刷新页面app肯定第一个挂载)

解决方案就是用路由守卫做判断,没有用户数据就派发请求。

这里我们先把派发home里。先把请求用户数据的接口写好:

//13.请求用户数据的接口
// /api/user/passport/auth/getUserInfo
export const reqUserInfo = () => {
    return requests.get('/user/passport/auth/getUserInfo');
}

vuex保存用户数据到仓库。

//3.请求用户数据
async getUserInfo({commit}) {
    let result = await reqUserInfo();
    if(result.code == 200) {
        console.log(result);
        commit('GETUSERINFO',result.data);
    }else {
        console.log('请求用户信息失败,原因是:',result.message);
    }
}

先在home页派发请求(实际是不对的,去别的页面刷新就没用户名了)

在这里插入图片描述

(4)退出登录

Header组件中,读取vuex的用户数据,拿到用户名

 <p>尚品汇欢迎您!</p>
 <p v-show="!userName">
     <span></span>
     <router-link to="/login">登录</router-link>
     <router-link to="/register" class="register">免费注册</router-link>
 </p>
 <p v-show="userName">
     <span>{{ userName }}</span>
     <router-link to="/login" class="register" @click.native="logout">退出登录</router-link>
 </p>
.......

<script>
	computed: {
	    userName() {
	        return this.$store.state.login.userInfo.name;
	    }
	}
</script>

<router-link>添加点击事件(别忘了加上个native),删除仓库的用户数据,删除用户的token

//退出登录,删除用户数据,删除token,跳回登录页
logout() {
    this.$store.state.login.userInfo = {}; //删除仓库数据,不知道直接这样好不好
    localStorage.removeItem('token');  //删除token
}

(5)路由守卫(有点意思)

这里看起来比较绕,其实很简单,就三层逻辑
1、用户有没有登录(有没有token)

//前置路由守卫
router.beforeEach(async (to,form,next) => {
    // 加了这个守卫,不写next(),就不会放行
    let token = localStorage.getItem('token'); //读取token的值
    //1.1用户是否登录(有没有token)
    if(token) {
        //2.1登录了就不能再回到登录页
        if(to.path == '/login') {
            next('/');
        }
        //2.2登陆了去其他的页面
        else {
            //3.1如果有用户数据,放行
            if(store.state.login.userInfo.name) {
                next();
            }
            //3.2如果没有用户数据,先请求成功再放行
            else {
                try {
                    //这个请求在挂载之前,所以刷新也会先请求
                    await store.dispatch('login/getUserInfo');
                    next();
                }catch(err) {
                    console.log('请求用户数据失败!',err);
                    //这里还有一种情况,token过期请求不到
                    //那么就要清空token,重新登录
                    localStorage.removeItem('token');
                    next('/login');
                }
            }
        }
    }
    //1.2如果没有登录
    else {
        //没登录不能去的路由地址
        let pages = ['/trade','/pay','/paysuccess','/center/myorder'];
        if(pages.includes(to.path)) {
            //如果没登陆往这几个页面跳,就回到登录页,并传想去的页面的地址
            //这样能提升用户体验,登录完成后直接跳到刚才的页面
            next(`/login?redirect=${to.path}`);
        }else {
            next();
        }
    }
})

后面的支付部分我简单看了一下,比较简单,就是请求数据展示数据,elementUI展示收款二维码,收款反复发请求直到付款成功等,没有什么难点,就不做了。

完结撒花!!后面还会有更多项目的笔记,欢迎大家关注我和我一起攻克前端项目

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值