目录

  • 登录与注册(重要)
  • 静态组件
  • 注册页面
  • 获取验证码
  • 完成注册
  • 登录页面
  • 登录跳转
  • token获取用户信息
  • 退出登录
  • 导航守卫


登录与注册(重要)

静态组件

  • assets文件夹:放置全部组件共用静态资源
  • 在样式中也可以使用@符号【src别名】,切记要在前面加一个~

注册页面

获取验证码

1、写接口

//获取验证码   地址:/api/user/passport/sendCode/{phone}   请求方法:GET   参数:需要
export const reqGetCode = (phone)=> requests({url:`/user/passport/sendCode/${phone}`,method:'GET'})

2、vuex三连环

import { reqGetCode } from "@/api"
//登录与注册的模块
const state = {
    code:''
}
const mutations = {
    GETCODE(state,code){
        state.code = code
    }
}
const actions = {
    //获取验证码
    async getCode({commit},phone){
        let result = await reqGetCode(phone)
        if(result.code == 200){
            commit('GETCODE',result.data)
            return 'ok'
        }else{
            return Promise.reject(new Error('faile'))
        }
    }
}
const getters = {}
export default {
    state,
    mutations,
    actions,
    getters
}

获取验证码的这个接口,把验证码返回,但是正常情况后台把验证码发到用户手机上
3、点击事件

async getCode(){
          try {
            const{phone} = this
            phone && (await this.$store.dispatch('getCode',phone))
            //验证码直接填写到框内
            this.code = this.$store.state.user.code
          } catch (error) {
            alert(error.message)
          }
        },

完成注册

1、接口

//注册  地址:/api/user/passport/register  请求方式:POST  参数:phone code password
export const reqUserRegister = (data)=> requests({url:'/user/passport/register',data,method:'POST'})

2、actions

//用户注册,未返回数据
    async userRegister({ commit }, user) {
        let result = await reqUserRegister(user)
        if (result.code) {
            return 'ok'
        } else {
            return Promise.reject(new Error('faile'))
        }
    }

3、点击事件

//用户注册
    async userRegister() {
      try {
        const { phone, code, password, password1 } = this;
        phone &&
          code &&
          password == password1 &&
          (await this.$store.dispatch("userRegister", {
            phone,
            code,
            password,
          }));
          this.$router.push('/login')
      } catch (error) {
        alert(error.message);
      }
    },

登录页面

登录跳转

1、收集表单数据
2、接口

//登录  地址:/api/user/passport/login  请求方式:POST  参数:phone password
export const reqUserLogin = (data)=> requests({url:'/user/passport/login',data,method:'POST'})

2、vuex

//登录业务[token]
async userLogin({ commit }, data) {
    let result = await reqUserLogin(data)
    //服务器下发的token是用户的唯一标识
    if (result.code == 200) {
        commit('USERLOGIN', result.data.token)
        return 'ok'
    } else {
        return Promise.reject(new Error('faile'))
    }
}

登录成功时,后台为了区分这个用户是谁,服务器会下发token【令牌:唯一标识】,一般会持久化存储token,再带着token找服务器要用的信息进行展示。
注意:vuex仓库存储数据不是持久化

3、点击事件

<button class="btn" @click.prevent="userLogin">登  录</button>

取消表单的默认行为

//用户登录
async userLogin() {
  try {
    const { phone, password } = this;
    phone &&
      password &&
      (await this.$store.dispatch("userLogin", { phone, password }));
    this.$router.push("/home");
  } catch (error) {
    alert(error.message);
  }
},

token获取用户信息

1、接口

//携带token获取用户的信息  地址:/api/user/passport/auth/getUserInfo  请求方式:GET
export const reqUserInfo = ()=> requests({url:'/user/passport/auth/getUserInfo',method:'GET'})

2、在请求拦截器中在请求头携带token

//判断需要携带token
if(store.state.user.token){
    config.headers.token = store.state.user.token
}

3、vuex

//获取用户信息
    async getUserInfo({commit}){
        let result = await reqUserInfo()
        if(result.code == 200){
            commit('GETUSERINFO',result.data)
            return 'ok'
        }else{
            return Promise.reject(new Error('faile'))
        }
    },

4、在TheHome组件挂载完毕之后派发action

//获取用户信息在首页展示
    this.$store.dispatch('getUserInfo',this.token)

5、在TheHeader组件展示数据

computed:{
    userName(){
        return this.$store.state.user.userInfo.name
    }
}
<p v-if="!userName">
	<span>请</span>
    <!-- 声名式导航:务必要有to属性 -->
	<router-link to="/login">登录</router-link>
    <router-link to="/register" class="register">免费注册</router-link>
</p>
<p v-else>
	<a>{{userName}}</a>
    <a class="register">退出登录</a>
</p>

6、当获取到token时持久化存储token

export const setToken = (token)=> {
    localStorage.setItem('TOKEN',token) 
}
export const getToken = ()=> {
    return localStorage.getItem('TOKEN') 
}

获得之后本地存储

setToken(result.data.token)

state中获得

token:getToken(),

逻辑:
当未发起请求时,state中的token无法在本地中找到,即为null。当第一次发起请求即登录成功之后,token就已经本地存储了,当再次刷新时state中的token可以获得本地存储的token,所以再次刷新仍有token。

退出登录

1、接口

//退出登录  地址:/api/user/passport/logout  请求方式:GET
export const reqLogout = ()=> requests({url:'/user/passport/logout',method:'GET'})

2、actions

//退出登录
async userLogout({commit}){
    let result = await reqLogout()
    if(result.code == 200){
        //action中不能操作state
        commit('CLEAR')
        return'ok'
    }else{
        return Promise.reject(new Error('faile'))
    }
}

3、mutations

export const removeToken = ()=> {
    localStorage.removeItem('TOKEN')
}
CLEAR(state){
        state.token = ''
        state.userInfo = {}
        removeToken()
    }

4、点击事件

//退出登录
async logout(){
    //1、发请求
    //2、清除项目当中的数据【userInfo/token】
    try {
        await this.$store.dispatch('userLogout')
        //回到首页
        this.$router.push('/home')
    } catch (error) {
        alert(error.message)
    } 
}

导航守卫

全局守卫:项目中,只要发生路由的变化,守卫就能监听到

//全局守卫:前置守卫(在路由跳转之间进行判断)
router.beforeEach(async(to,from,next)=>{
    //to:跳转到哪一个组件
    //from:从哪个路由来
    //next:放行函数 next()   next('/login')放行到指定路由   next(false)
    let token = store.state.user.token
    let name = store.state.user.name
    if(token){
        if(to.path == '/login'){
            next('/')
        }else{
            //登录了,去的不是login
            if(name){
                next()
            }else{
                //没有用户信息,派发action
                try {
                    //获取成功
                    await store.dispatch('getUserInfo')
                    next()
                } catch (error) {
                    //token失效了
                    await store.dispatch('userLogout')
                    next('/login')
                } 
            }  
        }
    }else{
        next()
    }
})
export default router

TheHome组件派发的获取用户信息action删掉