需求
设计下面后台管理界面的路由。
我想出有两种方式实现,分别是
- 使用嵌套路由实现
- 使用路由+动态组件实现
下面我将对比下这两种实现的不同,以便借助这个例子深入学习下vueRouter
使用嵌套路由实现
页面的路由设计如下
如果一个tab使用一个router-view,那么还要使用 命名视图,会使得情况变得更加复杂。
App.vue
|_ router-view
↓
BackstageManager.vue
|_ router-view
↓
业务界面
const routes = [
{
path: '/backstageManager',
name: 'BackstageManagerPage',
component: () => import(/* webpackChunkName: "about" */ '../views/backstageManager/BackstageManagerPage.vue'),
children: [
{
// 用户管理
path: 'userManeger',
name: 'UserManeger',
component: () => import(/* webpackChunkName: "about" */ '../views/backstageManager/UserManeger.vue')
},
{
// 商品管理
path: 'goodManger',
name: 'GoodManger',
component: () => import(/* webpackChunkName: "about" */ '../views/backstageManager/GoodManger.vue')
},
]
}
]
要注意的点
嵌套路由官方文档强调了一句话:
注意,以 / 开头的嵌套路径将被视为根路径。这允许你利用组件嵌套,而不必使用嵌套的 URL
怎么理解这句话呢?
- 以 / 开头的情况
{
path: '/backstageManager',
name: 'BackstageManagerPage',
component: () => import(/* webpackChunkName: "about" */ '../views/backstageManager/BackstageManagerPage.vue'),
children: [{
// path以/开头,假设项目根目录为 http://project/
// 则访问 http://project/userManeger可以访问到UserManeger,并且UserManeger会在BackstageManagerPage组件里
// 用户管理
path: '/userManeger',
name: 'UserManeger',
component: () => import(/* webpackChunkName: "about" */ '../views/backstageManager/UserManeger.vue')
}]
}
- 不以 / 开头的情况
{
path: '/backstageManager',
name: 'BackstageManagerPage',
component: () => import(/* webpackChunkName: "about" */ '../views/backstageManager/BackstageManagerPage.vue'),
children: [{
// path不以/开头,假设项目根目录为 http://project/
// 则访问 http://project/backstageManager/userManeger可以访问到UserManeger
// 用户管理
path: 'userManeger',
name: 'UserManeger',
component: () => import(/* webpackChunkName: "about" */ '../views/backstageManager/UserManeger.vue')
}]
}
总结,嵌套路由如果以 / 开头,会让逻辑变得很混乱,最好不要使用!
使用路由+动态组件实现
页面的路由设计如下
App.vue
|_ router-view
↓
BackstageManager.vue
|_ tab1里的component -> 业务界面1
|_ tab2里的component -> 业务界面2
const routes = [
{
path: '/backstageManager',
name: 'BackstageManagerPage',
component: () => import(/* webpackChunkName: "about" */ '../views/backstageManager/BackstageManagerPage.vue'),
},
{
path: '/backstageManager/dragGroupOneWay',
name: 'DragGroupOneWay',
component: () => import(/* webpackChunkName: "about" */ '../views/backstageManager/drag/DragGroupOneWay.vue')
},
{
path: '/backstageManager/dragGroupTwoWay',
name: 'DragGroupTwoWay',
component: () => import(/* webpackChunkName: "about" */ '../views/backstageManager/drag/DragGroupTwoWay.vue')
},
]
两种实现的对比
router-view的缓存维护
-
使用嵌套路由实现
需要维护router-view的缓存。因为在后台管理界面,多个tab对应着一个router-view,当切换tab而不是关闭tab的时候,切换回旧的tab的时候需要展示会原来的状态。并且删除tab后,重新打开tab后需要一个全新的状态。 -
使用路由+动态组件实现
不需要维护router-view的缓存。因为一个tab对应着一个component,切换tab不会改变别的tab的component
是否会改变后台管理界面的url
- 使用嵌套路由实现
会改变。url会随着点击不同的菜单,会显得很奇怪 - 使用路由+动态组件实现
不会改变
能否新开一个页面去独立访问后台管理的子页面
- 使用嵌套路由实现
不能。访问子页面的时候也会渲染父路由的组件! - 使用路由+动态组件实现
可以。
后台管理的嵌套页面,使用动态组件实现,而不是使用嵌套路由的方式实现。就可以实现,直接访问子页面路由可以单纯访问子页面,然后后台页面访问子页面的时候也不会更改路由
补充
动态组件
// 使用动态组件 + 动态导入
<el-tabs v-model="activeTabId" type="border-card" id="centerTab" closable @tab-remove="handleRemoveTab">
<el-tab-pane v-for="(menu, index) in tabList" :key="menu.id + index" :label="menu.name" :name="menu.id">
<component :is="menu.component" :key="menu.id"></component>
</el-tab-pane>
</el-tabs>
//这种是静态导入
import BackstageManagerMain from '@/views/backstageManager/BackstageManagerMain.vue'
data(){
return {
tabList: [
{
id: '0',
name: '主页',
routerPath: '/',
// import() 是动态导入,import方法
component: () => import(`@/views/backstageManager/BackstageManagerMain.vue`)
// 可以使用静态导入的组件
// component: BackstageManagerMain
}
]
}
}
如果没有登录,直接访问后台页面如何拦截
这时候就可以用到导航守卫了!
导航守卫,可以添加token判断,校验用户是否有登陆。如果有登陆则跳转到首页,没登陆就跳转到登陆页!
$router 和 $route的区别
https://www.cnblogs.com/czy960731/p/9288830.html
命名视图 与 嵌套路由
命名视图:在一个页面中展示两个平行的组件
嵌套路由:一个组件嵌套着另外一个组件