Vue-router 使用详解
1. 说明
重要文件版本
- “vue”: “^2.4.2”,
- “vue-router”: “^2.7.0”,
2. 项目引入
1. 下载
npm install --save vue-router
2. 导入到项目中并使用
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);
3. 定义路由
// 引入组件
import Home from '@/views/Home';
// 定义路由
const routes = [
{
path: '/home',
component: Home
},
...
]
// 创建路由实例,并导入配置参数
const router = new Router({
routes
})
// 挂载到根实例上
new Vue({
el: '#app',
router,
template: '<app/>',
components: { App }
});
4. 组件中使用
<!-- 跳转 -->
<router-link :to="{ path: `/home` }"></router-link>
<!-- 渲染路由 -->
<router-view></router-view>
3. Router 构造配置
1. routes
路由配置,是一个包含不同路径配置的数组
const routes = [
{
path: '/',
component: Home
},
...
]
1. path 匹配路径
一个代表路径的字符串
路由匹配可以是动态的,把某种模式匹配到的所有路由,都映射到同个组件上,可以通过
this.$route.params
获取的到变动的部分
const routes = [
{
path: '/' // 普通路径
path: '/home/:username' // 动态路由 '/user/a' '/user/b' 都会匹配到同一个路由
}
]
2. name 命名路由
通过设置 name 给路由加一个标识,使用的时候可以更方便
const routes = [
{
path: '/user/:userId',
name: 'user', // 设置命名
component: User
},
...
];
// 链接到命名路由
'<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>'
3. redirect 重定向
当用户访问一个链接时,替换他的路径,并转到相应的路由
const routes = [
{
path: '/',
component: Home,
// 普通的重定向
redirect: '/home',
// 重定向到命名路由
redirect: { name: 'home' },
// 根据 参数配置重定向的位置
redirect: to => {
// to 代表当前配置的路由对象
console.log(to);
// 需返回一个 重定向到的 路由
return {
name: 'home'
};
},
},
...
];
4. alias 别名
设置别名,可以让你访问 ‘/test/ccc’的时候渲染 path 为 ‘/’ 的 UI
const routes = [
{
path: '/',
component: Home,
alias: '/test/ccc' // 访问 '/test/ccc' 显示的页面与 '/' 一致
}
...
];
5. props 组件传参
const routes = [
{
path: '/home/:username',
component: Home,
props: true, // path 中动态部分成为了组件的 prop
props: { face: 'none', should: false }, // 设置静态的 prop
props: (route) => { // 静态、路由 prop 都可配置
console.log(route);
return {
face: 'show',
username: route.params.username
};
}
}
]
- 不设置 props,要在渲染的组件中获取 username 需要 this.$route.params.username
- 设置 props: true 后 username 会成为组件的一个 prop 直接声明 props: [‘username’] 即可
- 设置 props: {} 一个属性对象,对象中内容将直接作为组件的 props
- 设置 props: (route) => ({属性对象}) 可以将静态值与路由的值结合作为 props
6. children 嵌套路由
children 下的写法与 routes 一致
const routes = [
{
path: '/home',
component: Home,
children: [
{
/*
当 '/home' 时匹配成功,表示不匹配下一级路由时的默认显示
*/
path: '',
component: HomeDefault
},
{
/*
当 '/home/report' 匹配成功
Report 会被渲染在 Home 的 <router-view> 中
*/
path: 'report',
component: Report
}
]
}
]
2. mode
用于配置路由模式
- hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器。
- history: 依赖 HTML5 History API 和服务器配置。
- abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。
vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。
如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。
const router = new VueRouter({
mode: 'history',
routes: [...]
})
3. base
应用的基路径 例如,如果整个单页应用服务在 /app/ 下,然后 base 就应该设为 “/app/”。
const router = new VueRouter({
base: '/admin',
routes: [...]
})
4. fallback
当浏览器不支持 history.pushState 控制路由是否应该回退到 hash 模式。默认值为 true。
const router = new VueRouter({
routes: [...],
fallback: true
})
4. 路由信息对象
表示当前激活的路由的状态信息,包含了当前URL解析得到的信息 在组件内通过 this.$route 得到
- $route.path: 对应当前路由的路径,总是解析为绝对路径
- $route.params: 一个 key/value 对象,包含了 动态片段 和 全匹配片段,如果没有路由参数,就是一个空对象。
- $route.query: 一个 key/value 对象,表示 URL 查询参数。
- $route.hash: 当前路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串。
- $route.fullPath: 完成解析后的 URL,包含查询参数和 hash 的完整路径。
- $route.matched: 一个数组,包含当前路由的所有嵌套路径片段的 路由记录 。路由记录就是 routes 配置数组中的对象副本
- $route.name: 当前路由的名称,如果有的话
5. 导航守卫
就是在路由变化前后对是否跳转做一些判断
一般参数 to from next
- to: Route: 即将要进入的目标 路由对象
- from: Route: 当前导航正要离开的路由
- next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
1. 全局守卫
- router.beforeEach: 全局前置守卫,每次路由改变都会被首先调用
- router.beforeResolve: 和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
- router.afterEach: 全局后置钩子,
2. 路由独享的守卫
可以在路由配置上直接定义 beforeEnter 守卫
3. 组件内守卫
可以在路由组件内直接定义以下路由导航守卫
- beforeRouteEnter: 当此守卫执行前,组件实例还没被创建,所以不能访问 this
- beforeRouteUpdate: 在当前路由改变,但是该组件被复用时调用(一般是动态路径跳转)可以访问 this
- beforeRouteLeave: 导航离开该组件的对应路由时调用,可以访问 this
4. 各个守卫函数触发顺序
// 配置路由
const router = new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'Hello',
component: HelloWorld,
},
{
path: '/home/:username',
name: 'home',
component: Home,
props: true,
beforeEnter: (to, from, next) => {
console.log('路由 /home beforeEnter 守卫');
next();
}
}
]
});
router.beforeEach((to, from, next) => {
console.log('全局 beforeEach 守卫');
next();
});
router.beforeResolve((to, from, next) => {
console.log('全局 beforeResolve 守卫');
next();
});
router.afterEach((to, from) => {
console.log('全局 afterEach 守卫');
});
// Home 组件内
export default {
data() {return {}},
beforeRouteEnter(to, from, next) {
console.log('组件内 beforeRouteEnter 守卫');
next();
},
beforeRouteUpdate(to, from, next) {
console.log('组件复用 beforeRouteUpdate 守卫');
next();
},
beforeRouteLeave(to, from, next) {
console.log('组件 beforeRouteLeave 守卫');
next();
},
}
// 触发,进入 '/'
/*
全局 beforeEach 守卫
全局 beforeResolve 守卫
全局 afterEach 守卫
*/
// 进入 '/home/a'
/*
全局 beforeEach 守卫
路由 /home beforeEnter 守卫
组件内 beforeRouteEnter 守卫
全局 beforeResolve 守卫
全局 afterEach 守卫
*/
// 跳转到 '/home/b'
/*
全局 beforeEach 守卫
组件复用 beforeRouteUpdate 守卫
全局 beforeResolve 守卫
全局 afterEach 守卫
*/
6. 编程式导航
在 Vue 实例内部使用
this.$router.[]
来调用当你点击 时,这个方法会在内部调用,所以说,点击 等同于调用 router.push(…)。
1. 参数规则
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
2. 方法
- router.push() 向 history 栈添加一个新的记录, 当用户点击浏览器后退按钮时,则回到之前的 URL。
- router.replace() 跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
- router.go(n) 这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。