Vue Router是Vue.js官方的路由管理器,它和Vue.js的核心深度集成,让构建单页应用变得轻而易举。
动态路由
动态路由允许你在路由路径中使用变量,这些变量可以从实际的URL中获取,并传递给对应的路由组件。
定义动态路由
在router.js
或router/index.js
中定义动态路由:
javascript
import Vue from 'vue';
import VueRouter from 'vue-router';
import User from './views/User.vue';
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{
path: '/user/:id',
component: User,
},
],
});
这里,:id
是一个动态段,它可以匹配任何字符串。
访问动态参数
在对应的组件中,你可以通过$route.params
访问动态参数:
javascript
export default {
data() {
return {};
},
created() {
console.log(this.$route.params.id);
},
};
嵌套路由
嵌套路由允许你定义子路由,这些子路由可以在父路由的路径下被访问。
javascript
import Vue from 'vue';
import VueRouter from 'vue-router';
import User from './views/User.vue';
import Posts from './views/Posts.vue';
import Post from './views/Post.vue';
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{
path: '/user/:id',
component: User,
children: [
{
path: 'posts',
component: Posts,
},
{
path: 'posts/:postId',
component: Post,
},
],
},
],
});
导航守卫
导航守卫是在路由发生改变前进行某些操作的机制,包括全局守卫、组件内的守卫和异步路由独享守卫。
全局前置守卫
全局前置守卫在路由跳转之前执行,可以用来控制导航:
javascript
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!auth.loggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next() // 确保一定要调用 next()!
}
})
组件内的守卫
组件内的守卫包括beforeRouteEnter
和beforeRouteUpdate
,它们分别在进入和更新路由时执行:
javascript
export default {
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
next(vm => {
// 通过 `vm` 访问组件实例
vm.title = to.params.id
})
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
this.title = to.params.id
next()
},
}
异步路由独享守卫
异步路由独享守卫在异步加载的路由组件中使用,可以用来控制路由的加载:
javascript
{
path: '/foo',
component: () => import(/* webpackChunkName: "group-foo" */ './Foo'),
beforeEnter: (to, from, next) => {
// ...
}
}
实战案例:用户认证系统
假设我们有一个用户认证系统,只有登录用户才能访问特定的页面。我们可以使用导航守卫来实现这一功能:
javascript
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from './views/Home.vue';
import Profile from './views/Profile.vue';
import Login from './views/Login.vue';
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{ path: '/', component: Home },
{
path: '/profile',
component: Profile,
meta: { requiresAuth: true },
},
{ path: '/login', component: Login },
],
});
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!auth.loggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath },
});
} else {
next();
}
} else {
next(); // 确保一定要调用 next()!
}
});
export default router;
在这个例子中,我们定义了一个全局前置守卫,检查用户是否已登录。如果用户试图访问需要认证的页面但尚未登录,他们将被重定向到登录页面。
总结
Vue Router的动态路由和导航守卫机制为构建复杂单页应用提供了强大的工具。动态路由使你能够根据实际URL中的参数灵活地调整组件的行为,而导航守卫则允许你在路由跳转前后执行自定义逻辑,如权限检查、数据预取等。通过本教程的学习,你应该能够掌握Vue Router的核心功能,并将其应用于实际项目中。