小言_互联网的博客

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

584人阅读  评论(0)

一、完成注册部分

(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)路由守卫(有点意思)

这里看起来比较绕,其实很简单,就三层逻辑

//前置路由守卫
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展示收款二维码,收款反复发请求直到付款成功等,没有什么难点,就不做了。

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


转载:https://blog.csdn.net/weixin_42044763/article/details/128831711
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场