介绍
Vue Router 是 Vue.js 官方的路由管理器。
所谓路由,是指解析地址并获取资源的过程。
基础
安装
npm i -S vue-router
使用
// main.js
// 导入vue和vue-router
import Vue from 'vue';
import VueRouter from 'vue-router';
// 安装vue-router,实则调用其install方法
Vue.use(VueRouter);
// 导入组件
import Foo from '@/components/foo';
import Bar from '@/components/bar';
import Logs from '@/components/logs';
import NotFound from '@/components/not-found';
// 创建路由匹配表
const routes = [
// 匹配到'/foo'时,切换为组件Foo
{ path: '/foo', nama: 'Foo', component: Foo },
// 匹配到'/bar'时,切换为组件Bar
{ path: '/bar', nama: 'Bar', component: Bar },
// 匹配到`/logs/aaa/bbb`时,切换为组件Logs,
// 其中,参数user等于'aaa',参数date等于'bbb'
{ path: '/logs/:user/:date', name: 'Logs', component: Logs },
// 匹配到'/redirect'时,URL改变并导航至'/foo'
{ path: '/redirect', redirect: '/foo' },
// 匹配到'/alias'时,URL不变但导航至'/foo'
{ path: '/alias', alias: '/foo' },
// 匹配所有路径,因为越后面的路由优先级越低,所以常用于监听404
{ path: '*', nama: 'NotFound', component: NotFound },
];
// 创建路由实例
const router = new VueRouter({ routes });
// 创建vue实例, 并将router绑定到该实例上
const app = new Vue({
router,
}).$mount('#app');
<template>
<div id="app">
<router-link to="/foo">Route to Foo</router-link>
<router-link to="/bar">Route to Bar</router-link>
<a @click="routeToLogs('xiaoming', '2020-08-15')">Route to Logs</a>
<router-view />
</div>
</template>
<script>
export default {
watch: {
// 监测路由变化
$route(to, from) {
console.log(to.params); // 路由参数
console.log(to.query); // 查询参数
},
},
methods: {
// 路由跳转
routeToLogs(user, date) {
this.$router.push({
name: 'Logs',
params: {
user,
date,
},
query: {},
});
},
},
};
</script>
进阶
编程式导航
const router = this.$router;
// push:导航至指定路径,并添加导航记录
router.push('/user');
router.push({
name: 'User',
params: { userId: '123' },
query: { plan: 'private' },
onComplete() {},
onAbort() {},
});
// replace:导航至指定路径,并替换当前导航记录
router.replace({});
// go:前进相应步数,为负数则后退
router.go(2);
router.go(-1);
导航守卫
导航守卫方法通常接受三个参数:
to:当前匹配到的路由。from:原路由。next:调用该方法,才会“通过”守卫,成功跳转。
// router.js
new VueRouter({
routes: [
{
// 路由独享守卫
beforeEnter(to, from, next) {},
},
],
// 全局守卫
beforeEach(to, from, next) {},
beforeResolve(to, from, next) {},
afterEach(to, from, next) {},
});
// component.vue
export default {
name: 'Component',
// 组件内守卫
beforeRouteEnter(to, from, next) {},
beforeRouteUpdate(to, from, next) {},
beforeRouteLeave(to, from, next) {},
};
注意,路由参数和查询参数的改变,不会触发导航守卫。
命名视图
// ComponentDefault、ComponentA和componentB,
// 分别被渲染到对应name的<router-view>中
const routes = [
{
path: '/',
components: {
default: ComponentDefault,
viewA: ComponentA,
viewB: ComponentB,
},
},
];
<div id="app">
<!--name默认为default-->
<router-view />
<router-view name="viewA" />
<router-view name="viewB" />
</div>
动态路由匹配
获取路由参数:
this.$router.params;
路由组件传参:
const routes = [
// 布尔模式:将路由参数传递给User的props
{ path: '/user/:id', component: User, props: true },
// 对象模式:将props传递给User的props
{ path: '/user/:id', component: User, props: {} },
// 函数模式:将props的返回值传递给User的props
{ path: '/user/:id', component: User, props(route) {} },
];
嵌套路由匹配
// 匹配到'/user/:id/profile'时,
// 组件User会被渲染到组件App的<router-view>中,
// 组件UserProfile会被选绕到组件User的<router-view>中
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
path: 'profile',
component: UserProfile,
},
{
path: 'posts',
component: UserPosts,
},
],
},
];
<!--App.vue-->
<div id="app">
<router-view />
</div>
<!--User.vue-->
<div id="user">
<h2>UserID: {{ $route.params.id }}</h2>
<router-view />
</div>
路由命名
const route = {
name: 'foo',
};
this.$router.push({
name: 'foo',
});
路由元信息
const route = {
meta: {
requireAuth: true,
requireLog: true,
},
};
路由滚动行为
// savedPosition是滚动条位置(仅前进/后退时可用)
new VueRouter({
scrollBehavior(to, from, savedPosition) {
// 返回滚动位置
return {
x: 0,
y: 32,
};
},
});
路由过渡动效
详见此文。
<!--App.vue-->
<transition>
<router-view></router-view>
</transition>
路由懒加载
方法一,使用 Vue 异步组件:
const route = {
path: '/',
component: () =>
Promise.resolve({
// 组件定义对象
}),
};
方法二,使用import语法:
const route = {
path: '/',
component: () => import('@/components/component-name'),
};
API
router
// 配置项
const router = new VueRouter({
mode,
base,
routes,
linkActiveClass,
linkExactActiveClass,
parseQuery,
stringifyQuery, //自定义解析/反解析函数
scrollBehavior,
});
// 实例属性和方法
router.app; // 挂载的Vue根实例
router.mode;
router.currentRoute; // 当前对应的路由信息对象
router.beforeEach();
router.beforeResolve();
router.afterEach();
router.push();
router.replace();
router.forward();
router.back();
router.getMatchedComponents(); // 返回当前路由匹配的组件数组
router.addRoutes(routes); // 添加路由规则
router.onReady(callback);
router.onError(callback);
// 在组件中,通过this.$router访问router
this.$router;
route
// 配置项
const route = {
path,
name,
meta,
redirect,
alias,
children,
component,
components,
props,
beforeEnter,
caseSensitive, // 是否大小写敏感
};
// 实例属性
route.path; // 路由路径
route.fullPath; // 完整路径
route.hash; // 路由hash值
route.params;
route.query;
route.name; // 路由名
route.redirectedFrom; // 重定向的来源路由
// 在组件中,通过this.$route访问当前匹配到的route
this.$route;
// props
to, replace, append // 传入path或route
tag // 渲染成的标签种类
active-class, exact-active-class // 激活样式
exact // 是否精确匹配,默认为包含匹配(/a/b也会匹配到/a)
event // 触发导航的事件,默认为click
name; // 视图名