若依框架 vue3 去掉首页,登录后跳转到动态路由的第一个

1,015 阅读2分钟

若依框架 vue3 去掉首页,根据动态权限,登录后跳转到动态路由的第一个菜单,涉及改动界面:

image.png

  1. src/permission.js 修改路由跳转
router.beforeEach((to, from, next) => {
  NProgress.start()
  if (getToken()) {
    to.meta.title && useSettingsStore().setTitle(to.meta.title)
    /* has token*/
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      if (useUserStore().roles.length === 0) {
        isRelogin.show = true
        // 判断当前用户是否已拉取完user_info信息
        useUserStore().getInfo().then(() => {
          isRelogin.show = false
          usePermissionStore().generateRoutes().then(accessRoutes => {
            // 根据roles权限生成可访问的路由表
            accessRoutes.forEach(route => {
              if (!isHttp(route.path)) {
                router.addRoute(route) // 动态添加可访问路由表
              }
            })
            // 当登录之后,直接通过ip地址和端口号访问时,跳转到第一个路由页面indexPage
            if (to.fullPath == '/') {
              let pathIndex = ''
              if (accessRoutes[0].path == '/') {     
                pathIndex = accessRoutes[0].path + accessRoutes[0].children[0].path
              } else {
                 pathIndex = accessRoutes[0].path + '/' + accessRoutes[0].children[0].path
              }
              next({ path: pathIndex, replace: true }) // hack方法 确保addRoutes已完成
            } else {
              next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
            }
            
          })
        }).catch(err => {
          useUserStore().logOut().then(() => {
            ElMessage.error(err)
            next({ path: '/' })
          })
        })
      } else {
        next()
      }
    }
  } else {
    // 没有token
    if (whiteList.indexOf(to.path) !== -1) {
      // 在免登录白名单,直接进入
      next()
    } else {
      next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
      NProgress.done()
    }
  }
})

  1. src/components/Breadcrumb/index.vue 注释一些代码
function getBreadcrumb() {
  // only show routes with meta.title
  let matched = route.matched.filter(item => item.meta && item.meta.title);
  const first = matched[0]
  // 判断是否为首页
  // if (!isDashboard(first)) {
  //   matched = [{ path: '/index', meta: { title: '首页' } }].concat(matched)
  // }

  levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
}
  1. src/layout/components/Sidebar/Logo.vue

image.png

  1. src/layout/components/TagsView/index.vue
function isAffix(tag) {
  if (tag.fullPath == usePermissionStore().indexPage) {
    return true
  } else {
    return tag.meta && tag.meta.affix
  }
}

function isFirstView() {
  try {
    return selectedTag.value.fullPath === usePermissionStore().indexPage || selectedTag.value.fullPath === visitedViews.value[1].fullPath
  } catch (err) {
    return false
  }
}

function toLastView(visitedViews, view) {
  const latestView = visitedViews.slice(-1)[0]
  if (latestView) {
    router.push(latestView.fullPath)
  } else {
    // now the default is to redirect to the home page if there is no tags-view,
    // you can adjust it according to your needs.
    if (view.name === 'Dashboard') {
      // to reload home page
      router.replace({ path: '/redirect' + view.fullPath })
    } else {
      router.push(usePermissionStore()?.indexPage)

    }
  }
}

function openMenu(tag, e) {
  if (tag.fullPath != usePermissionStore().indexPage) {
    const menuMinWidth = 105
    const offsetLeft = proxy.$el.getBoundingClientRect().left // container margin left
    const offsetWidth = proxy.$el.offsetWidth // container width
    const maxLeft = offsetWidth - menuMinWidth // left boundary
    const l = e.clientX - offsetLeft + 15 // 15: margin right

    if (l > maxLeft) {
      left.value = maxLeft
    } else {
      left.value = l
    }

    top.value = e.clientY
    visible.value = true
    selectedTag.value = tag

  } else {
    visible.value = false
  }
}
  1. src/plugins/tab.js
  // 关闭指定tab页签
  closePage(obj) {
    if (obj === undefined) {
      return useTagsViewStore().delView(router.currentRoute.value).then(({ visitedViews }) => {
        const latestView = visitedViews.slice(-1)[0]
        if (latestView) {
          return router.push(latestView.fullPath)
        }
        return router.push(usePermissionStore()?.indexPage);
      });
    }
    return useTagsViewStore().delView(obj);
  },
  1. src/router/indexjs 注释index
  // {
  //   path: '',
  //   component: Layout,
  //   redirect: '/index',
  //   children: [
  //     {
  //       path: '/index',
  //       component: () => import('@/views/index'),
  //       name: 'Index',
  //       meta: { title: '首页', icon: 'dashboard', affix: true }
  //     }
  //   ]
  // },
  1. src/store/modules/permission.js
const usePermissionStore = defineStore(
  'permission',
  {
    state: () => ({
      routes: [],
      addRoutes: [],
      defaultRoutes: [],
      topbarRouters: [],
      sidebarRouters: [],
      indexPage: ''   //修改默认首页
    }),
    actions: {
      setRoutes(routes) {
        this.addRoutes = routes
        this.routes = constantRoutes.concat(routes)
      },
      setDefaultRoutes(routes) {
        this.defaultRoutes = constantRoutes.concat(routes)
      },
      setTopbarRoutes(routes) {
        this.topbarRouters = routes
      },
      setSidebarRouters(routes) {
        this.sidebarRouters = routes
      },
      setIndexPages(routes) {
        this.indexPage = routes
      },
      generateRoutes(roles) {
        return new Promise(resolve => {
          // 向后端请求路由数据
          getRouters().then(res => {
            const sdata = JSON.parse(JSON.stringify(res.data))
            const rdata = JSON.parse(JSON.stringify(res.data))
            const defaultData = JSON.parse(JSON.stringify(res.data))
             let firstPage = ''
            //通过权限返回菜单去避免 如有首页权限 出现//index 情况
            if (res.data[0].path == '/') {
              firstPage = res.data[0].path + res.data[0].children[0].path
            } else {
              firstPage = res.data[0].path + '/' + res.data[0].children[0].path
            }
            this.setIndexPages(firstPage)

            const sidebarRoutes = filterAsyncRouter(sdata)
            const rewriteRoutes = filterAsyncRouter(rdata, false, true)
            const defaultRoutes = filterAsyncRouter(defaultData)
            const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
            asyncRoutes.forEach(route => { router.addRoute(route) })
            this.setRoutes(rewriteRoutes)
            this.setSidebarRouters(constantRoutes.concat(sidebarRoutes))
            this.setDefaultRoutes(sidebarRoutes)
            this.setTopbarRoutes(defaultRoutes)
            resolve(rewriteRoutes)
          })
        })
      }
    }
  })
  1. src/utils/request.js
 if (code === 401) {
      if (!isRelogin.show) {
        isRelogin.show = true;
        ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
          isRelogin.show = false;
          useUserStore().logOut().then(() => {
            location.href = usePermissionStore().indexPage;
          })
      }).catch(() => {
        isRelogin.show = false;
      });
    }
  1. src/views/error/401.vue 和 src/views/error/404.vue
import usePermissionStore from '@/store/modules/permission'
const permissionStore = usePermissionStore()

  <router-link :to="permissionStore.indexPage">回首页</router-link>