• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 路由元信息

    有时,你可能希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等。这些事情可以通过接收属性对象的meta属性来实现,并且它可以在路由地址和导航守卫上都被访问到。定义路由的时候你可以这样配置meta字段。

    在需要登录验证的路由元信息里,加入自定义的登录验证标识requiresAuth

    const routes = [
      {
        path: '/posts',
        component: PostsLayout,
        children: [
          {
            path: 'new',
            component: PostsNew,
            // 只有经过身份验证的用户才能创建帖子
            meta: { requiresAuth: true }
          },
          {
            path: ':id',
            component: PostsDetail
            // 任何人都可以阅读文章
            meta: { requiresAuth: false }
          }
        ]
      }
    ]
    

    那么如何访问这个meta字段呢?

    首先,我们称呼routes配置中的每个路由对象为路由记录。路由记录可以是嵌套的,因此,当一个路由匹配成功后,它可能匹配多个路由记录。

    例如,根据上面的路由配置,/posts/new这个 URL 将会匹配父路由记录(path:'/posts')以及子路由记录(path:'new')。

    一个路由匹配到的所有路由记录,会暴露为$route对象(还有在导航守卫中的路由对象)的$route.matched数组。我们需要遍历这个数组来检查路由记录中的meta字段。因此,我们需要遍历$route.matched来检查路由记录中的meta字段。

    router.beforeEach((to, from, next) => {
      some() 方法检查数组中的任何元素是否通过测试(作为函数提供)
      if (to.matched.some(record => record.meta.requiresAuth)) {
        // this route requires auth, check if logged in
        // if not, redirect to login page.
        if (!auth.loggedIn()) {
          next({
            path: '/login',
            query: { redirect: to.fullPath }
          })
        } else {
          next()
        }
      } else {
        next() // 确保一定要调用 next()
      }
    })
    

    但是Vue Router还为你提供了一个$route.meta方法,它是一个非递归合并所有meta字段的(从父字段到子字段)的方法。这意味着你可以简单地写:

    router.beforeEach((to, from) => {
      // 而不是去检查每条路由记录
      // to.matched.some(record => record.meta.requiresAuth)
      if (to.meta.requiresAuth && !auth.isLoggedIn()) {
        // 此路由需要授权,请检查是否已登录
        // 如果没有,则重定向到登录页面
        return {
          path: '/login',
          // 保存我们所在的位置,以便以后再来
          query: { redirect: to.fullPath },
        }
      }
    })
    


    TypeScript

    可以通过扩展RouteMeta接口来输入meta字段:

    // typings.d.ts or router.ts
    import 'vue-router'
    
    declare module 'vue-router' {
      interface RouteMeta {
        // 是可选的
        isAdmin?: boolean
        // 每个路由都必须声明
        requiresAuth: boolean
      }
    }
    

    上篇:导航守卫

    下篇:过渡动效