Vue-Router 学习笔记

最后更新:
阅读次数:

学习 Vue 快一年了,然而路由方面用的还不是得心应手,索性就重新再看一遍,然后以一种更通俗的方式来记录它的常用语法。

路由基本概念

先看代码!

const routes = [
{
path: "*",
name: "default",
component: Default
},
{
path: "/home",
component: Home
},
{
path: "/about",
name: "about",
component: About
}
];

const router = new VueRouter({
routes
});
  • 称呼 routes 配置中的每个路由对象为一条路由记录
  • router 为一个路由实例,它包含了多条路由记录

路由注入

通过在 Vue 根实例的 router 配置传入 router 实例,可以将下面的两个属性注入到每个子组件。

  • 注入的属性
    • this.$route: 当前激活的路由信息对象
    • this.$router: router 实例
const router = new VueRouter({
routes
});

const app = new Vue({
el: "#app",
router
});

编程式导航

  • this.$router.pushthis.$router.replace 的第二和第三个参数均为可选参数。
  • 可通过 this.$route.query 来获取当前的查询参数
// 向 history 栈添加一个新的记录
this.$router.push(
{
path: "/home",
query: {
uid: 666
}
},
onComplete,
onAbort
);
// 替换当前的 history 记录
this.$router.replace(
{
path: "/home",
query: {
uid: 666
}
},
onComplete,
onAbort
);
// 跳转到指定的 history 记录
this.$router.go(1);
this.$router.go(-1);

动态路由

  • 动态路由中,可以设置多段路径参数,对应的值都会设置到 $route.params
模式匹配路径$route.params
/user/:username/user/william{ username: ‘william’ }
/user/:username/:type/user/william/about{ username: ‘william’, type: ‘about’ }
  • 在动态路由中,当从路径 /user/aa/bb 导航到 /user/cc/dd 时,默认会复用组件实例,这也意味着组件的生命周期钩子不会再被调用。

  • 如果想要在动态路由发生变化时作出响应,可以给组件添加 beforeRouteUpdate 钩子捕获路由变化,但是记得在这个钩子中执行 next 函数,否则不会发生路由跳转。

const User = {
name: "user-page",
template: `<div>
<h1>User Page</h1>
<h3>User Name:{{ $route.params.username }}</h3>
<p>Type:{{ $route.params.type }}</p>
</div>`,
beforeRouteUpdate(to, from, next) {
console.log(arguments);
next();
}
};

const router = new VueRouter({
routes: [
{
// 动态路由
path: "/user/:username/:type",
name: "user",
component: User
}
]
});

嵌套路由

const User = {
name: "user-page",
template: `<div>
<h3>User Page({{ $routes.params.id }})</h3>
<router-view></router-view>
</div>`
};

const UserProfile = {
name: "user-profile",
template: `<div>
<h3>user profile page</h3>
</div>`
};

const UserGallery = {
name: "user-gallery",
template: `<div>
<h3>user gallery page</h3>
</div>`
};

const router = new VueRouter({
routes: [
{
// 动态路由
path: "/user/:id",
component: User,
children: [
{
path: "profile",
component: UserProfile
},
{
path: "gallery",
component: UserGallery
}
]
}
]
});

命名视图

  • 如果同级需要展示多个视图,那么请使用命名视图
<router-view></router-view>
<router-view name="view1"></router-view>
<router-view name="view2"></router-view>
const Header = {
name: "Header",
template: `<div><h2>Header(默认视图)</h2></div>`
};

const Body = {
name: "Body",
template: `<div><h2>Body(视图1)</h2></div>`
};

const Footer = {
name: "Footer",
template: `<div><h2>Footer(视图2)</h2></div>`
};

const router = new VueRouter({
routes: [
{
path: "/",
components: {
default: Header,
view1: Body,
view2: Footer
}
}
]
});

路由的重定向和别名

  • 重定向: 访问 / 时,会自动跳转到 /home
const router = new VueRouter({
routes: [
{
path: "/",
redirect: "/home"
},
{
path: "/home",
component: Home
}
]
});
  • 别名: 访问 /home 与访问 / 的效果一样
const router = new VueRouter({
routes: [
{
path: "/",
alias: "/home",
component: Home
}
]
});

路由的钩子与守卫

钩子: 钩子会在合适的时机被调用,但钩子本身不会阻碍路由的进行
守卫: 相比钩子,守卫可以中断路由的进行,只有在守卫中手动的调用 next() 方法,路由才会继续进行

守卫,有趣的名字!

  • 全局入口守卫: beforeEach,每次在进入新的路由前都会被调用
const router = new VueRouter({
routes
});

router.beforeEach((to, from, next) => {
console.log("全局入口守卫被调用~");
next();
});
  • 全局出口钩子: afterEach,每次在退出当前路由前都会被调用
const router = new VueRouter({
routes
});

router.afterEach((to, from) => {
console.log("全局出口钩子被调用~");
});
  • 单个路由的入口守卫: beforeEnter
// 局部,针对特定路由
const router = new VueRouter({
routes: [
{
path: "/home",
component: Home,
beforeEnter(to, from, next) {
console.log("home 入口守卫~");
next();
}
}
]
});
  • 用于组件内的路由守卫
    • beforeRouteEnter
    • beforeRouteUpdate
    • beforeRouteLeave
const User = {
name: "user-page",
template: `<div>
<h1>User Page</h1>
<h3>User Name:{{ $route.params.username }}</h3>
<p>Type:{{ $route.params.type }}</p>
</div>`,
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 在此不能获取组件实例 `this`,因为在该守卫执行前,组件实例还没被创建
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 可以访问组件实例 `this`
// 常用于动态路由的跳转,比如 /user/aaa -> /user/bbb
},
beforeRouteLeave(to, from, next) {
// 离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
};

HTML5 History 模式

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。

使用下面的代码可以开启 HTML5 History 模式,但是还需要服务器进行相关的配置才能用。(参见 vue-router 官方文档

const router = new VueRouter({
mode: "history",
routes
});

切换路由的滚动行为

使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样,可以在此配置切换路由的滚动行为。

  • 注意: 这个功能只在 HTML5 history 模式 下可用。
const router = new VueRouter({
mode: "history",
routes,
scrollBehavior(to, from, savedPosition) {
// return 期望滚动到哪个的位置
}
});

这一块儿还没用过,待补充。(链接