Vue 路由元信息
  • 官网解释

    定义路由的时候可以配置 meta 字段:

    const router = new VueRouter({
      routes: [
        {
          path: '/foo',
          component: Foo,
          children: [
            {
              path: 'bar',
              component: Bar,
              // a meta field
              meta: { requiresAuth: true }
            }
          ]
        }
      ]
    })
    

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

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

    例如,根据上面的路由配置,/foo/bar 这个 URL 将会匹配父路由记录以及子路由记录。

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

    下面例子展示在全局导航守卫中检查元字段:

    router.beforeEach((to, from, next) => {
      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()
      }
    })
    
  • 自编示例

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>路由元信息</title>
    </head>
    <body>
    <div id="app">
        <p>
            <router-link :to="{name:'home'}">首页</router-link>
            <router-link :to="{name:'news'}">新闻</router-link>
            <router-link :to="{name:'profile'}">用户中心</router-link>
        </p>
        <router-view></router-view>
    </div>
    
    <template id="home">
        <div>这是首页</div>
    </template>
    
    <template id="news">
        <div>
            <p>这是新闻</p>
            <router-link :to="{name:'tech'}">科技新闻</router-link>
            <router-link :to="{name:'financial'}">财经新闻</router-link>
            <router-view></router-view>
        </div>
    </template>
    
    <template id="tech">
        <div>这是科技新闻</div>
    </template>
    
    <template id="financial">
        <div>这是财经新闻</div>
    </template>
    
    <template id="profile">
        <div>用户信息展示</div>
    </template>
    
    <template id="login">
        <div>用户登录界面</div>
    </template>
    
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script>
        const Home = { template: '#home' }
        const News = { template: '#news' }
        const TechNews = { template: '#tech' }
        const FinancialNews = { template: '#financial' }
        const Profile = { template: '#profile' }
        const Login = { template: '#login' }
    
        routes = [
            {
                path: '',
                redirect: {name: 'home'}
            },
            {
                path: '/homes',
                component: Home,
                name: 'home',
                meta: {  // 添加路由元信息
                    name: '首页'
                }
            },
            {
                path: '/news',
                component: News,
                meta: {
                    name: '新闻'
                },
                children: [
                    {
                        path: '',
                        redirect: 'tech',
                        name: 'news',
                    },
                    {
                        path: 'tech',
                        component: TechNews,
                        name: 'tech' ,
                        meta: {
                            name: '科技新闻'
                        }
                    },
                    {
                        path: 'financial',
                        component: FinancialNews,
                        name: 'financial',
                        meta: {
                            name: '财经新闻'
                        }
                    }
                ]
            },
            {
                path: '/Profile',
                component: Profile,
                name: 'profile',
                meta: {
                    name: '用户中心',
                    requiresAuth: true
                }
            },
            {
                path: '/login',
                component: Login,
                name: 'login',
                meta: {
                    name: '用户登录'
                }
            }
        ]
        router = new VueRouter({
            routes
        })
        // 登录验证
        router.beforeEach((to, from ,next) => {
            if(to.matched.some( record => record.meta.requiresAuth)){
                console.log(this)  // 注意这里this是windows
                if(!$auth_check()){
                    next({name: 'login'})
                    return null
                }
            }
            next()
        })
        // 修改页面标题
        router.beforeEach((to, from ,next) => {
            console.log(to) // to为要跳转的Rout实例
            if(to.matched.length) {
                document.title = to.matched[to.matched.length - 1].meta.name
            }
            next()
        })
    
        Vue.prototype.$auth_check = () => {
            return true
        }
        const app = new Vue({
            router,
            methods: {
                click(){
                    console.log(this)
                }
            },
            created() {
                window.$auth_check = () => {
                    return true
                }
            }
        }).$mount('#app')
    </script>
    </body>
    </html>