vue2.x 路由
2020/7/29 vue
# 开始使用
import Vue from 'vue'
import VueRouter from 'vue-router'
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 全局路由钩子
- beforeEach
router.beforeEach((to, from, next) => {
//一般登录拦截用这个,也叫导航钩子守卫
if (path === '/login') {
next()
return
}
if (token) {
next();
}
})
// beforeResolve
// afterEach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 组件路由钩子
- beforeRouteEnter
beforeRouteEnter (to, from, next) {
// 这里还无法访问到组件实例,this === undefined
next( vm => {
// 通过 `vm` 访问组件实例
})
}
// beforeRouteUpdate
// beforeRouteLeave
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# Vue.$router
// 跳转到不同的url,但这个方法回向history栈添加一个记录,点击后退会返回到上一个页面
this.$router.push()
// 不会有记录
this.$router.replace()
// n可为正数可为负数。正数返回上一个页面,类似 window.history.go(n)
this.$router.go(n)
1
2
3
4
5
6
2
3
4
5
6
# Vue.$route
// 获取通过 params 或/:id传参的参数
this.$route.params.id
// 获取通过 query 传参的参数
this.$route.query.id
1
2
3
4
5
2
3
4
5
# router render
component: {
render: h => h("router-view");
}
1
2
3
2
3
# 路由传参
- 方式一
// 路由定义
{
path: '/describe/:id',
name: 'Describe',
component: Describe
}
// 页面传参
this.$router.push({
path: `/describe/${id}`,
})
// 页面获取
this.$route.params.id
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 方式二
// 路由定义
{
path: '/describe',
name: 'Describe',
component: Describe
}
// 页面传参
this.$router.push({
name: 'Describe',
params: {
id: id
}
})
// 页面获取
this.$route.params.id
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 方式三
// 路由定义
{
path: '/describe',
name: 'Describe',
component: Describe
}
// 页面传参
this.$router.push({
path: '/describe',
query: {
id: id
}
)
// 页面获取
this.$route.query.id
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 路由拆分
- 目录
# router
├── router
│ ├── index.js
│ └── router.js
# views目录下
views
├── Page
│ ├── api.js # 接口定义
│ ├── router.js # 路由配置
│ └── src
│ └── layered
│ ├── detail.vue
│ ├── index.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './router'
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'history',
routes
})
export default router
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
src/router/router.js
// 利用 webpack 读取 views 目录下的 router.js
const routerFile = require.context('../', true, /^\.\/views\/[\w.-]+\/router.js$/)
// 返回的 routerFile.keys() 是一个路由配置的路径数组列表 ['./views/Page/router.js']
// 循环递归调用 routerFile 去解析 每一项的路径地址 './views/Page/router.js'
// 返回 文件内容: Module { default: { path: "/page", name: 'xxx', children:[{},...]}, ... }
// 获取返回路由集合
const routesConfig = (r => {
return r.keys().map(key => r(key).default)
})(routerFile)
// redirect
const redirectConfig = {
path: '*',
redirect: '/'
}
const routes = routesConfig.concat(redirectConfig)
return routes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
src/views/Page/router.js
export default {
path: '/page',
name: 'Page',
component: () => import('@/components/RouterCache.vue'),
meta: {
keepAlive: true,
title: 'Page A',
},
children: [
{
path: 'detail/:id',
name: 'PageDetail',
component: () => import('./src/detail/index.vue'),
meta: {
keepAlive: true,
}
}
]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 缓存和动画
<transition>
<keep-alive :include="['a', 'b']">
//或include="a,b" :include="/a|b/",a 和 b 表示组件的 name
//因为有些页面,如试试数据统计,要实时刷新,所以就不需要缓存
<router-view/> //路由标签
</keep-alive>
<router-view exclude="c"/>
// c 表示组件的 name值
</transition>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- Cached Router:
RouterCache.vue
<template>
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
</div>
</template>
<script>
export default {
name: 'RouterCache'
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# router-view 的 key
// Vue 会复用相同组件, key可以解决 组件的 created 和 mounted 不调用问题
<router-view :key="$route.fullPath"></router-view>
1
2
2
# vue-router3.x错误拦截
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
Vue.use(VueRouter)
// 隐藏vue-router在3.0版本控制台错误信息(跳转相同路径会报错)
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function(location) {
return originalPush.call(this, location).catch(err => err)
}
const originalReplace = VueRouter.prototype.replace
VueRouter.prototype.replace = function(location) {
return originalReplace.call(this, location).catch(err => err)
}
const router = new VueRouter({
mode: 'history',
base: process.env.VUE_APP_HASH ? '/' : process.env.BASE_URL,
routes
})
export default router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# router全局添加query参数
// 全局添加biz query参数: 仅限于vue-router
const QUERY_BIZID_NAME = 'bizid'
export const addRouterBizQuery = (router) => {
router.beforeEach((to, from, next) => {
const bizId = to.query[QUERY_BIZID_NAME]
const curId = getCurrentBizId()
if (!bizId || !isValidBizId(bizId) || bizId !== curId) {
const query = {
...to.query,
[QUERY_BIZID_NAME]: curId
}
next &&
next({
...to,
query: query
})
} else {
next && next()
}
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21