二次开发--登录页到主页

302 阅读3分钟

登录页成功之后,跳转进入主页

tip: 这里dispatch是异步的,需要加async await

async doLogin() {
      try {
       await this.$store.dispatch('user/userLogin', this.loginForm)
       this.$router.push('/')
      } catch (err) {
        alert('用户登录,失败')
        console.log('用户登录,失败', err)
      }
    },

路由守卫的格式

路由守卫中一定执行next

以用token为核心控制路由页面的跳转(permission.js).png

-   to:要去哪个页面
-   from:从哪里来
-   next:它是一个函数。
1.  如果直接放行 next()
2.  如果要跳到其它页 next(其它页)

router.beforeEach((to, from, next) => {
  console.log(to, from)
  next()
})

路由导航守卫-实现两个跳转限制

白名单:那些不需要token就可以直接访问的页面

  • 登陆用户不能再次回到login
  • 没有登陆就不能访问除login之外的其它页
  • router.beforeEach(回调(三个参数:to,from,next

实现两个跳转限制.JPG

router.beforeEach((to, from, next) => {
  console.log(to)
  // 获取token
  console.log('全局前置路由守卫 获取token ', store.getters.token)
  // 有token,已经登陆了
  if (store.getters.token) {
    // 如果要去login,则直接跳到主页
    if (to.path === '/login') {
      console.log('已经登陆了,就不能再访问login,应该去主页')
      next('/')
    } else {
      // 有token,要去的不是login,就直接放行
      next()
    }
  } else {
    // 没有token,
    // 要去的页面在白名单中,放行
    // to.path在whiteList数组中
    if (whiteList.includes(to.path)) {
      next()
    } else {
      console.log('没有token,就不能访问白名单之外的页面,应该去登陆')
      next('/login')
    }
  }
})

includes: 在一个数组里找一个数据 ,如果找到为true,找不到为false **
这里的图标我们使用了 svg,设置颜色需要使用svg标签的fill属性

调用action

时机分析:

  1. 因为依赖token去获取用户数据 所以必须要在获取了token之后才能调用这个action函数
  2. 因为跳转到首页后就要显示数据了,所以要求我们在跳转进入首页之前就提前拿回用户个人数据

确保两件事情:

  1. token已经存在
  2. 成功获取会数据之后才能进行跳转(同步)
`src/permission.js`
// 引入路由配置
import router from './router'
// 引入vuex,因为要获取其中token
import store from './store'
// 引入一份进度条插件
import NProgress from 'nprogress'
import 'nprogress/nprogress.css' // 引入进度条样式

// 白名单: 不需要token就可以直接访问的页面
const whiteList = ['/login'] // no redirect whitelist

// 全局前置路由守卫
//  to:要去哪个页面
//  from:从哪里来
//  next:它是一个函数。
//     如果直接放行 next()
//     如果要跳到其它页 next(其它页)
router.beforeEach(async(to, from, next) => {
  NProgress.start() // 启动进度条
  // 获取token
  console.log('全局前置路由守卫 获取token ', store.getters.token)
  // 有token,已经登陆了
  if (store.getters.token) {
    // 如果要去login,则直接跳到主页
    if (to.path === '/login') {
      console.log('已经登陆了,就不能再访问login,应该去主页')
      next('/')
    } else {
      // 有token,要去的不是login,就直接放行
      // 派发action来发aja进一步获取用户信息
      // 由于dispatch过程是异步的,要加await,才能保证是先获取用户信息,再跳转的
      await store.dispatch('user/getUserInfo')
      next()
    }
  } else {
    // 没有token,
    // 要去的页面在白名单中,放行
    // to.path在whiteList数组中
    if (whiteList.includes(to.path)) {
      next()
    } else {
      console.log('没有token,就不能访问白名单之外的页面,应该去登陆')
      next('/login')
    }
  }
})

router.afterEach(() => {
  // 结束进度条
  NProgress.done()
})

Token失效处理

后端:收到用户访问某个接口时,检查当前token是否失效,如果token已经失效,返给前端一个约定好的状态码 10002
前端:在响应拦截器中,分析接口的返回值,如果状态码为10002, 则进行token失效操作 token超时处理.JPG 由于页面跳转要用到路由,先引入路由:

import router from '@/router'
error => {
    if (error.response && error.response.data && error.response.data.code === 10002) {
      Message({
        message: '请重新登陆',
        type: 'error',
        duration: 5 * 1000
      })
      // token失效了
      // 1. 手动执行logout, 删除token
      store.dispatch('user/logout')
      // 2. 回到登陆页
      router.push('/login')
    } else {
      Message({
        message: error.message,
        type: 'error',
        duration: 5 * 1000
      })
    }
    return Promise.reject(error)
  }
  • 以上方案为后端主导的方案,前端只需要拿到错误码做业务处理即可,此方案也是常用且安全的最优方案 小提示:模拟token失效,找到Application面板 找到cookies把 token数据右键之后删除几位 重新刷新页面