美文网首页
【vue-router】项目设计

【vue-router】项目设计

作者: 嘻洋洋 | 来源:发表于2021-11-17 17:31 被阅读0次

下面介绍在实际项目中使用vue-router,整体规划设计

1. 规划内容

(1)核心的几个关键路由:登录页面,主页,错误页面。
(2)页面访问控制:有些页面不需要做登录控制
(3)动态路由:模块菜单有一部分是数据库配置的,因此除了固定路由外,有一部分是动态添加的路由

2. 详细设计

2.1 全局路由

全局路由指独立的,不需要验证是已登录的页面,不需要用到导航卫士,不需要使用嵌入Main框架:比如登录页,错误页,外部系统调用的页面(通过签名授权)

// 全局路由(无需嵌套上左右整体布局)
const globalRoutes = [
  { path: '/404', component: _import('common/404'), name: '404', meta: { title: '404未找到' } },
  { path: '/login', component: _import('common/Login'), name: 'login', meta: { title: '登录' } },
  { path: '/', component: _import('common/Login'), name: 'first', meta: { title: '登录' } },
  { path: '/scm2erp/consignmentPurchaseInvoice', component: _import('modules/erp/scm_settlement/consignment_purchase_invoice/ConsignmentPurchaseInvoice'), name: 'consignmentPurchaseInvoice', meta: {title: '代销买入发票'}},
  { path: '/scm2erp/dxInputInvoice', component: _import('modules/erp/scm_settlement/consignment_purchase_invoice/DxInputInvoice'), name: 'dxInputInvoice', meta: {title: '代销录入发票'}},
]

2.2 Main路由

(1)路由设计
Main路由就是登录后进入的首页,在这个首页里面同时 (同级) 展示多个组件,比如有MainNavbar (顶部), MainSidebar (侧导航) 和 MainContent (主内容) 。其中MainNavbar和MainSidebar是常规组件。MainContent是嵌套视图组件【Main的子组件】,所有页面显示在其中(含有路由的出口)。Main本身也是一个视图组件。

    <template v-if="!loading">
      <main-navbar />
      <main-sidebar />
      <div class="site-content__wrapper" :style="{ 'min-height': documentClientHeight + 'px' }">
        <main-content v-if="!$store.state.common.contentIsNeedRefresh" />
      </div>
    </template>
//  引入视图组件
import MainNavbar from './MainNavbar'
import MainSidebar from './MainSidebar'
import MainContent from './MainContent'

  components: {
    MainNavbar,
    MainSidebar,
    MainContent
  },

因此设计成嵌套路由

// 主入口路由(需嵌套上左右整体布局)
const mainRoutes = {
  path: '/',
  component: _import('Main'),
  name: 'main',
  redirect: { name: 'home' },
  meta: { title: '主入口整体布局' },
  // 固定路由
  children: [
    { path: '/home', component: _import('common/Home'), name: 'home', meta: { title: '首页' } },
    { path: '/theme', component: _import('common/Theme'), name: 'theme', meta: { title: '主题' } },
    { path: '/supplier_settlement-OutAccountAudit', component: _import('modules/erp/sup_settlement/OutAccountAudit'), name: 'supplier_settlement-OutAccountAudit', meta: { title: '供应商出账数据稽核', isTab: true } }
   ]
}

在Main主路由中的所有页面的嵌套路由分两种,一种是如上的固定路由,不属于菜单,不通过数据库配置。
另外一种是动态路由,如通过数据库配置的菜单,因此需要动态添加路由:

//路由规则有 name,并且已经存在一个与之相同的名字,则会覆盖它。因此另外取一个名字
    mainRoutes.name = 'main-dynamic'
    mainRoutes.children = routes
    router.addRoutes([
      mainRoutes,
      { path: '*', redirect: { name: '404' } }
    ])
// 为了避免刷新后清空,需要本地先存
    sessionStorage.setItem('dynamicMenuRoutes', JSON.stringify(mainRoutes.children || '[]'))

(2)访问控制
访问Main路由之前,验证是否已经登录成功,因此Main路由这里使用路由独享的守卫,如:

  beforeEnter (to, from, next) {
    let token = Vue.cookie.get('token')
    if (!token || !/\S/.test(token)) {
      clearLoginInfo()
      next({ name: 'login' })
    }
    next()
  }

2.3 全局守卫

访问路由前,如果请求的路径不是全局路由,并且没有添加动态路由,需要重新加载路由后,继续访问,目的解决刷新问题导致动态路由丢失。

router.beforeEach((to, from, next) => {
  if (router.options.isAddDynamicMenuRoutes || fnCurrentRouteType(to, globalRoutes) === 'global') {
     next()
  } else {
    http({
      url: http.adornUrl('/sys/menu/nav'),
      method: 'get',
      params: http.adornParams()
    }).then(({ data }) => {
      if (data && data.code === 0) {
        fnAddDynamicMenuRoutes(data.menuList)
        router.options.isAddDynamicMenuRoutes = true
        sessionStorage.setItem('menuList', JSON.stringify(data.menuList || '[]'))
        sessionStorage.setItem('permissions', JSON.stringify(data.permissions || '[]'))
        next({ ...to, replace: true })
      } else {
        sessionStorage.setItem('menuList', '[]')
        sessionStorage.setItem('permissions', '[]')
        next()
      }
    }).catch((e) => {
      console.log(`%c${e} 请求菜单列表和权限失败,跳转至登录页!!`, 'color:blue')
      router.push({ name: 'login' })
    })
  }
})

3. 其它设计

3.1 根路径匹配多个路由

登录页面要使用根路径,Main路由也使用根路径,目的为是以 / 开头的嵌套路径会被当作根路径。 充分的使用嵌套组件而无须设置嵌套的路径。由于同一个路径可以匹配多个路由,所以是可以实现的,同时要把登录页面路由放在Main路由前面。当路径匹配到多个路由时,优选匹配前面的。

3.2 匹配任意路径

对应输入错误地址时,我们不希望显示404,能够显示相应错误页面。因此路由最后面添加一个对于所有路径都能匹配一个的路由。当匹配不到路由,就匹配错误页面路由。

    router.addRoutes([
      mainRoutes,
      { path: '*', redirect: { name: '404' } }
    ])

相关文章

网友评论

      本文标题:【vue-router】项目设计

      本文链接:https://www.haomeiwen.com/subject/jaicgltx.html