路由重定向、别名及元信息

路由重定向

在日常的项目开发中,虽然有时设置的页面路径不一致,但却希望跳转到同一个页面,或者说是之前设置好的路由信息,由于某种程序逻辑,需要将之前的页面导航到同一个组件上,这时就需要用到重定向功能。

重定向也是通过设置路由信息 routes 来完成的,具体如示例代码7-10-1所示。

示例代码7-10-1 路由重定向
const router = VueRouter.createRouter({
    history: VueRouter.createWebHashHistory(),
    routes: [
        { path: '/a', redirect: '/b' }, // 直接从/a重定向到/b
        { path: '/c', redirect: { name: 'd' }} // 从/c重定向到命名路由d
        { path: '/e', redirect: (to) => {
            // 方法接收目标路由作为参数
            // 用 return 返回重定向的字符串路径或者路由对象
        }}
    ]
})

从上面的代码可知,redirect 可以接收一个路径字符串或者路由对象以及一个返回路径或者路由对象的方法,其中直接设置路径字符串很好理解,如果是一个路由对象,就像之前在讲解 router.push 方法时传递的路由对象,可以设置传递的参数,代码如下:

const router = VueRouter.createRouter({
    history: VueRouter.createWebHashHistory(),
    routes: [
        {
            path: '/',
            redirect: (to)=>{
                return {
                    path:'/header',
                    query:{
                        id:to.query.id
                    }
                }
            }
        },
        {
            path: '/header',
            name:'header',
            component: Header
        }
    ]
})

需要说明的是,导航守卫不会作用在 redirect 之前的路由上,只会作用在 redirect 之后的目标路由上,并且一个路由如果设置了 redirect,那么这个路由本身对应的组件视图也不会生效,也就是说无须给 redirect 路由配置 component。唯一的例外是嵌套路由:如果一个路由记录有 childrenredirect 属性,那么为了保证 children 有对应的上级组件,则需要配置 component 属性。

路由别名

“重定向” 的意思是,当用户访问 /a 时,URL 将会被替换成 /b,然后匹配路由为 /b。那么 “别名” 又是什么呢?

/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是匹配路由为 /a,就像用户访问 /a 一样,如示例代码7-10-2所示。

const router = VueRouter.createRouter({
    history: VueRouter.createWebHashHistory(),
    routes: [
        { path: '/a', component: A, alias: '/b' }
    ]
})

“别名” 的功能让我们可以自由地将 UI 结构映射到任意的 URL,而不是受限于设置的嵌套路由结构,代码如下:

const routes = [
    {
        path: '/users',
        component: UsersLayout,
        children: [
            // 为这 3 个 URL 呈现 UserList: - /users  - /users/list - /people
            { path: '', component: UserList, alias: ['/people', 'list'] },
        ],
    },
]

路由元数据

在设置路由信息时,每个路由都有一个元数据字段,可以在这里设置一些自定义信息,供页面组件、导航守卫和路由钩子函数使用。例如,将每个页面的 title 都写在 meta 中来统一维护,如示例代码7-10-3所示。

示例代码7-10-3 路由元数据meta
const router =  VueRouter.createRouter({
    history: VueRouter.createWebHashHistory(),
    routes: [
        {
            path: '/',
            name: 'index',
            component: Index,
            meta: { // 在这里设置meta信息
                title: '首页'
            }
        },
        {
            path: '/user',
            name: 'user',
            component: User,
            meta: { // 在这里设置meta信息
                title: '用户页'
            }
        }
    ]
})

在组件中,可以通过 this.$route.meta.title 获取路由元信息中的数据,在插值表达式中使用 $route.meta.title,代码如下:

const User = {
    created(){
        console.log(this.$route.meta.title)
    },
    template: '<h1>Title {{ $route.meta.title }}</h1>'
}

可以在全局前置路由守卫 beforeEach 中获取 meta 信息,然后修改 HTML 页面的 title,代码如下:

router.beforeEach((to, from, next)=> {
    window.document.title = to.meta.title;
    next();
})