用户登录后,不需要显示同样的首页,登录后直接跳转到路由菜单第一个页面。

本文章是从其他多个文章中总结出符合自己的内容。如有抄袭请见谅。只做学习记录使用。

1、修改文件 src\permission.js 

防止当用户登录之后,点击浏览器做上角的后退按钮, 会出现跳到404的情况。

    /* has token*/
    if (to.path === '/login') {

      // 修改默认首页。
      // 注释
      // next({ path: '/' })

      // 添加
      location.href = store.state.permission.indexPage
      // 修改默认首页。

      NProgress.done()
    } else if (isWhiteList(to.path)) {

没有token需要跳转到登录页面。

    // 没有token
    if (isWhiteList(to.path)) {
      // 在免登录白名单,直接进入
      next()
    } else {

      // 修改默认首页。
      // 注释
      // next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页

      // 添加
      next(`/login`) // 否则全部重定向到登录页。
      // 修改默认首页。

      NProgress.done()
    }

完整代码如下:

import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth'
import { isPathMatch } from '@/utils/validate'
import { isRelogin } from '@/utils/request'

NProgress.configure({ showSpinner: false })

const whiteList = ['/login', '/register']

const isWhiteList = (path) => {
  return whiteList.some(pattern => isPathMatch(pattern, path))
}

router.beforeEach((to, from, next) => {
  NProgress.start()
  if (getToken()) {
    to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
    /* has token*/
    if (to.path === '/login') {

      // 修改默认首页。
      // 注释
      // next({ path: '/' })

      // 添加
      location.href = store.state.permission.indexPage
      // 修改默认首页。

      NProgress.done()
    } else if (isWhiteList(to.path)) {
      next()
    } else {
      if (store.getters.roles.length === 0) {
        isRelogin.show = true
        // 判断当前用户是否已拉取完user_info信息
        store.dispatch('GetInfo').then(() => {
          isRelogin.show = false
          store.dispatch('GenerateRoutes').then(accessRoutes => {
            // 根据roles权限生成可访问的路由表
            router.addRoutes(accessRoutes) // 动态添加可访问路由表
            next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
          })
        }).catch(err => {
            store.dispatch('LogOut').then(() => {
              Message.error(err)
              next({ path: '/' })
            })
          })
      } else {
        next()
      }
    }
  } else {
    // 没有token
    if (isWhiteList(to.path)) {
      // 在免登录白名单,直接进入
      next()
    } else {

      // 修改默认首页。
      // 注释
      // next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页

      // 添加
      next(`/login`) // 否则全部重定向到登录页。
      // 修改默认首页。

      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

2、修改文件 src\store\modules\permission.js

   添加首页变量定义

  state: {
    routes: [],
    addRoutes: [],
    defaultRoutes: [],
    topbarRouters: [],
    sidebarRouters: [],

    // 修改默认首页
    indexPage: ''
  },
  mutations: {
    SET_ROUTES: (state, routes) => {
      state.addRoutes = routes
      state.routes = constantRoutes.concat(routes)
    },
    SET_DEFAULT_ROUTES: (state, routes) => {
      state.defaultRoutes = constantRoutes.concat(routes)
    },
    SET_TOPBAR_ROUTES: (state, routes) => {
      state.topbarRouters = routes
    },
    SET_SIDEBAR_ROUTERS: (state, routes) => {
      state.sidebarRouters = routes
    },

    // 修改默认首页
    SET_INDEX_PAGE: (state, indexPage) => {
      state.indexPage = indexPage
    },
  },

取得新首页的路由信息

  actions: {
    // 生成路由
    GenerateRoutes({ commit }) {
      return new Promise(resolve => {
        // 向后端请求路由数据
        getRouters().then(res => {

          // 修改默认首页。
          // 添加
          const sdata = JSON.parse(JSON.stringify(res.data))
          const rdata = JSON.parse(JSON.stringify(res.data))
          
          // 登录后跳转404,要看看登录页url的redirect重定向值是什么。
          if(res.data.length > 0){
            // 登录的用户有菜单权限
            let pathIndex = ''
            // 第一个菜单要区分有子菜单和没有子菜单的情况
            if (res.data[0].path == '/') {
              // 一级子菜单
              pathIndex = res.data[0].path + res.data[0].children[0].path
            } else {
              if (res.data[0].children) {
                if (res.data[0].children[0].children && res.data[0].children[0].children.length > 0) {
                  // 三级子菜单
                  pathIndex = res.data[0].path + '/' + res.data[0].children[0].path + '/' + res.data[0].children[0].children[0].path
                } else {
                  // 二级子菜单
                  pathIndex = res.data[0].path + '/' + res.data[0].children[0].path
                }
              }
            }
            // console.log('store permission---', pathIndex)
            const sidebarRoutes = filterAsyncRouter(sdata)

            const rewriteRoutes = filterAsyncRouter(rdata, false, true)

            // 如果登录之后,用户跳到的路由是存在但没有权限的路由,那就要提示无权限。但是需要有一个接口返回全部路由来作为参考。这个功能后续再考虑是否完善。
            const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
            rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) // 当输入不存在的路由时,直接跳转到404
            router.addRoutes(asyncRoutes)
            commit('SET_ROUTES', rewriteRoutes)
            commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
            commit('SET_DEFAULT_ROUTES', sidebarRoutes)
            commit('SET_TOPBAR_ROUTES', sidebarRoutes)
            //修改默认首页
            commit('SET_INDEX_PAGE', pathIndex)
            resolve(rewriteRoutes)
          } else {
            // 登录的用户没有任何一个菜单权限
            Message({
              message: '非常抱歉,该用户没有菜单权限!',
              type: 'warning'
            });
            resolve()
          }
          

          // 注释
          // const sdata = JSON.parse(JSON.stringify(res.data))
          // const rdata = JSON.parse(JSON.stringify(res.data))
          // const sidebarRoutes = filterAsyncRouter(sdata)
          // const rewriteRoutes = filterAsyncRouter(rdata, false, true)
          // const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
          // rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
          // router.addRoutes(asyncRoutes)
          // commit('SET_ROUTES', rewriteRoutes)
          // commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
          // commit('SET_DEFAULT_ROUTES', sidebarRoutes)
          // commit('SET_TOPBAR_ROUTES', sidebarRoutes)
          // resolve(rewriteRoutes)

          // 修改默认首页。
        })
      })
    }
  }

完整代码如下:

import auth from '@/plugins/auth'
import router, { constantRoutes, dynamicRoutes } from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index'
import ParentView from '@/components/ParentView'
import InnerLink from '@/layout/components/InnerLink'

const permission = {
  state: {
    routes: [],
    addRoutes: [],
    defaultRoutes: [],
    topbarRouters: [],
    sidebarRouters: [],

    // 修改默认首页
    indexPage: ''
  },
  mutations: {
    SET_ROUTES: (state, routes) => {
      state.addRoutes = routes
      state.routes = constantRoutes.concat(routes)
    },
    SET_DEFAULT_ROUTES: (state, routes) => {
      state.defaultRoutes = constantRoutes.concat(routes)
    },
    SET_TOPBAR_ROUTES: (state, routes) => {
      state.topbarRouters = routes
    },
    SET_SIDEBAR_ROUTERS: (state, routes) => {
      state.sidebarRouters = routes
    },

    // 修改默认首页
    SET_INDEX_PAGE: (state, indexPage) => {
      state.indexPage = indexPage
    },
  },
  actions: {
    // 生成路由
    GenerateRoutes({ commit }) {
      return new Promise(resolve => {
        // 向后端请求路由数据
        getRouters().then(res => {

          // 修改默认首页。
          // 添加
          const sdata = JSON.parse(JSON.stringify(res.data))
          const rdata = JSON.parse(JSON.stringify(res.data))

          // 登录后跳转404,要看看登录页url的redirect重定向值是什么。
          if(res.data.length > 0){
            // 登录的用户有菜单权限
            let pathIndex = ''
            // 第一个菜单要区分有子菜单和没有子菜单的情况
            if (res.data[0].path == '/') {
              // 一级子菜单
              pathIndex = res.data[0].path + res.data[0].children[0].path
            } else {
              if (res.data[0].children) {
                if (res.data[0].children[0].children && res.data[0].children[0].children.length > 0) {
                  // 三级子菜单
                  pathIndex = res.data[0].path + '/' + res.data[0].children[0].path + '/' + res.data[0].children[0].children[0].path
                } else {
                  // 二级子菜单
                  pathIndex = res.data[0].path + '/' + res.data[0].children[0].path
                }
              }
            }
            // console.log('store permission---', pathIndex)
            const sidebarRoutes = filterAsyncRouter(sdata)

            const rewriteRoutes = filterAsyncRouter(rdata, false, true)

            // 如果登录之后,用户跳到的路由是存在但没有权限的路由,那就要提示无权限。但是需要有一个接口返回全部路由来作为参考。这个功能后续再考虑是否完善。
            const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
            rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) // 当输入不存在的路由时,直接跳转到404
            router.addRoutes(asyncRoutes)
            commit('SET_ROUTES', rewriteRoutes)
            commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
            commit('SET_DEFAULT_ROUTES', sidebarRoutes)
            commit('SET_TOPBAR_ROUTES', sidebarRoutes)
            //修改默认首页
            commit('SET_INDEX_PAGE', pathIndex)
            resolve(rewriteRoutes)
          } else {
            // 登录的用户没有任何一个菜单权限
            Message({
              message: '非常抱歉,该用户没有菜单权限!',
              type: 'warning'
            });
            resolve()
          }


          // 注释
          // const sdata = JSON.parse(JSON.stringify(res.data))
          // const rdata = JSON.parse(JSON.stringify(res.data))
          // const sidebarRoutes = filterAsyncRouter(sdata)
          // const rewriteRoutes = filterAsyncRouter(rdata, false, true)
          // const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
          // rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
          // router.addRoutes(asyncRoutes)
          // commit('SET_ROUTES', rewriteRoutes)
          // commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
          // commit('SET_DEFAULT_ROUTES', sidebarRoutes)
          // commit('SET_TOPBAR_ROUTES', sidebarRoutes)
          // resolve(rewriteRoutes)

          // 修改默认首页。
        })
      })
    }
  }
}

// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
  return asyncRouterMap.filter(route => {
    if (type && route.children) {
      route.children = filterChildren(route.children)
    }
    if (route.component) {
      // Layout ParentView 组件特殊处理
      if (route.component === 'Layout') {
        route.component = Layout
      } else if (route.component === 'ParentView') {
        route.component = ParentView
      } else if (route.component === 'InnerLink') {
        route.component = InnerLink
      } else {
        route.component = loadView(route.component)
      }
    }
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type)
    } else {
      delete route['children']
      delete route['redirect']
    }
    return true
  })
}

function filterChildren(childrenMap, lastRouter = false) {
  var children = []
  childrenMap.forEach(el => {
    el.path = lastRouter ? lastRouter.path + '/' + el.path : el.path
    if (el.children && el.children.length && el.component === 'ParentView') {
      children = children.concat(filterChildren(el.children, el))
    } else {
      children.push(el)
    }
  })
  return children
}

// 动态路由遍历,验证是否具备权限
export function filterDynamicRoutes(routes) {
  const res = []
  routes.forEach(route => {
    if (route.permissions) {
      if (auth.hasPermiOr(route.permissions)) {
        res.push(route)
      }
    } else if (route.roles) {
      if (auth.hasRoleOr(route.roles)) {
        res.push(route)
      }
    }
  })
  return res
}

export const loadView = (view) => {
  if (process.env.NODE_ENV === 'development') {
    return (resolve) => require([`@/views/${view}`], resolve)
  } else {
    // 使用 import 实现生产环境的路由懒加载
    return () => import(`@/views/${view}`)
  }
}

export default permission

3、修改文件 src\router\index.js 注释掉原首页路由信息

  // {
  //   path: '',
  //   component: Layout,
  //   redirect: 'index',
  //   children: [
  //     {
  //       path: 'index',
  //       component: () => import('@/views/index'),
  //       name: 'Index',
  //       meta: { title: '首页', icon: 'dashboard', affix: true }
  //     }
  //   ]
  // },

4、修改文件 src\utils\request.js

注:后经过测试,此处修改不需要。还是用原代码 location.href = '/index'

          store.dispatch('LogOut').then(() => {

            // 修改默认首页。
            // 注释
            // location.href = '/index'

            // 添加
            let indexurl = this.$store.state.permission.indexPage
            location.href = indexurl
            // 修改默认首页。

          })

完整代码如下:

// 响应拦截器
service.interceptors.response.use(res => {
    // 未设置状态码则默认成功状态
    const code = res.data.code || 200
    // 获取错误信息
    const msg = errorCode[code] || res.data.msg || errorCode['default']
    // 二进制数据则直接返回
    if (res.request.responseType ===  'blob' || res.request.responseType ===  'arraybuffer') {
      return res.data
    }
    if (code === 401) {
      if (!isRelogin.show) {
        isRelogin.show = true
        MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
          isRelogin.show = false
          store.dispatch('LogOut').then(() => {

            // 修改默认首页。
            // 注释
            // location.href = '/index'

            // 添加
            let indexurl = this.$store.state.permission.indexPage
            location.href = indexurl
            // 修改默认首页。

          })
      }).catch(() => {
        isRelogin.show = false
      })
    }
      return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
    } else if (code === 500) {
      Message({ message: msg, type: 'error' })
      return Promise.reject(new Error(msg))
    } else if (code === 601) {
      Message({ message: msg, type: 'warning' })
      return Promise.reject('error')
    } else if (code !== 200) {
      Notification.error({ title: msg })
      return Promise.reject('error')
    } else {
      return res.data
    }
  },
  error => {
    console.log('err' + error)
    let { message } = error
    if (message == "Network Error") {
      message = "后端接口连接异常"
    } else if (message.includes("timeout")) {
      message = "系统接口请求超时"
    } else if (message.includes("Request failed with status code")) {
      message = "系统接口" + message.slice(-3) + "异常"
    }
    Message({ message: message, type: 'error', duration: 5 * 1000 })
    return Promise.reject(error)
  }
)

5、修改文件 src\layout\components\Navbar.vue

修改logout函数

    logout() {
      this.$confirm('确定注销并退出系统吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$store.dispatch('LogOut').then(() => {

          // 修改默认首页。
          // 注释
          // location.href = '/index'

          // 添加
          let indexurl = this.$store.state.permission.indexPage
          console.log(indexurl)
          location.href = indexurl
          // 修改默认首页。

        })
      }).catch(() => {})
    }

6、修改文件 src\views\login.vue

修改登陆函数

    handleLogin() {
      this.$refs.loginForm.validate(valid => {
        if (valid) {
          this.loading = true
          if (this.loginForm.rememberMe) {
            Cookies.set("username", this.loginForm.username, { expires: 30 })
            Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 })
            Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 })
          } else {
            Cookies.remove("username")
            Cookies.remove("password")
            Cookies.remove('rememberMe')
          }
          this.$store.dispatch("Login", this.loginForm).then(() => {

            // 修改默认首页。
            // 注释
            // this.$router.push({ path: this.redirect || "/" }).catch(()=>{})
            
            // 添加
            // 1、跳到登录后指定跳转的页面或者登录后跳到首页
            // this.$router.push({ path: this.redirect || '/' }).catch(() => {})
            // 2、登录后跳到路由默认的第一个路由页面
            this.$store.dispatch('GetInfo').then(res => {
              // 拉取完user_info信息
              const roles = res.roles
              this.$store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => {
                // 根据roles权限生成可访问的路由表
                if(accessRoutes) {
                  // 登录用户有菜单权限。
                  // console.log(accessRoutes, from, to.fullPath)
                  this.$router.addRoutes(accessRoutes) // 动态添加可访问路由表
                  let pathIndex = ''
                  pathIndex = accessRoutes[0].path + '/' + accessRoutes[0].children[0].path // 设置默认首页地址indexPage
                  // console.log(this.redirect, pathIndex)
                  // 1、this.redirect == undefined,主要针对直接从http://172.16.6.205:9090/login,登入系统。
                  // 2、this.redirect == '/',主要针对直接从这个http://172.16.6.205:9090/login?redirect=%2F,登入系统。因为没有设置重定向的路由
                  // 如果登录的时候出现1、2两种情况,那么就跳到路由的第一个路由页面,如果登录的时候,有设置可以访问的重定向地址,那么登录后就跳到重定向地址。
                  if (pathIndex != '') {
                    this.$router.push({ path: this.redirect == '/' || this.redirect == undefined ? pathIndex : this.redirect }).catch(() => {}) // 跳转重定向页面或跳到默认首页indexPage
                  }
                } else {
                  // 登录的用户没有任何一个菜单路由权限,那么要去掉登录按钮的loading状态。从新获取验证码。
                  this.loading = false
                  this.getCode()
                }
              })
            }).catch(err => {
                this.$store.dispatch('LogOut').then(() => {
                  Message.error(err)
                  next({ path: '/login' })
                })
              })
            
            // 修改默认首页。

          }).catch(() => {
            this.loading = false
            if (this.captchaEnabled) {
              this.getCode()
            }
          })
        }
      })
    }

7、修改文件 src\components\Breadcrumb\index.vue

注释首页的判断

      // 判断是否为首页
      // if (!this.isDashboard(matched[0])) {
      //   matched = [{ path: "/index", meta: { title: "首页" } }].concat(matched)
      // }

8、修改文件 src\layout\components\TagsView\index.vue

添加关闭最后一个标签页的判断,不允许关闭。

    closeSelectedTag(view) {

      // 修改默认首页。
      // 添加
      if (this.visitedViews.length == 1) {
        this.$modal.msgWarning("当前为最后一个页签,不允许删除。");
        return;
      }
      // 修改默认首页。
      
      this.$tab.closePage(view).then(({ visitedViews }) => {
        if (this.isActive(view)) {
          this.toLastView(visitedViews, view)
        }
      })
    },

9、修改文件 src\views\error\404.vue和401.vue

修改页面的返回首页链接

<router-link :to="indexPage" class="bullshit__return-home">
  返回首页
</router-link>




export default {
  name: 'Page404',
  computed: {
    // 修改默认首页。
    // 添加
    ...mapState({
      indexPage: state => state.permission.indexPage,
    }),
    // 修改默认首页。
    message() {
      return '找不到网页!'
    }
  }
}

至此修改就完成了。测试通过。目前还没有发现有大问题。发现问题再进行修改吧。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐