Vue 0基础学习路线(26)—— 图解深度详述vue路由的路由元信息的使用和通过meta属性定义需要验证的路由及详细案例(附详细案例代码解析过程及版本迭代过程)

1. 引言

路由元信息类似鉴权,如果有些页面,不想用刚刚上一篇我们所写的savedPosition效果,如除了详情页,其他页面点击前进和后退都顶到头,这个时候怎么做呢?

如果死板地去一个一个判断,是非常麻烦的。

判断如果当前to的目标是view,像我们的例子,只有一个页面,还好说,如果上百个页面就没办法解决了。

因此我们可以利用路由元信息进行标注 ,它实际和标签自定义属性是一样的,这里实际就是路由的自定义属性。

2. 路由元信息

定义路由的时候可以配置 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()
  }
})

3. 通过 meta 定义要验证的路由

const router = new Router({
  routes: [
    {
      path: '/user',
      component: User,
      children: [
        {
          path: '',
          name: 'user',
          component: Profile,
          meta: { requiresAuth: true }
        },
        {
          path: 'cart',
          name: 'user-cart',
          component: Cart,
          meta: { requiresAuth: true }
        }
      ]
    }
  ]
})

const isLogin = true;

router.beforeEach((to, from, next) => {
  NProgress.start()

  if (to.meta.requiresAuth && !isLogin) {
      next({
        name: 'login',
      })
  } else {
    next()
  }
  
})

或者

const router = new Router({
  routes: [
    {
      path: '/user',
      component: User,
      meta: { requiresAuth: true }
      children: [
        {
          path: '',
          name: 'user',
          component: Profile
        },
        {
          path: 'cart',
          name: 'user-cart',
          component: Cart
        }
      ]
    }
  ]
})

const isLogin = true;

router.beforeEach((to, from, next) => {
  NProgress.start()

  if (to.matched.some(record => record.meta.requiresAuth) && !isLogin) {
      next({
        name: 'login',
      })
  } else {
    next()
  }
  
})

4. 实例

4.1 example01

实现除了详情页,其他页面点击前进和后退都顶到头。

路由下每个页面的meta属性,里面的值,随意定。 =>

定好之后我们就可以在scrollBehavior中进行判断了,如果当前页面的to下的meta属性下的该值为真就往下走。

\app\src\router\index.js

import Vue from 'vue';
import VueRouter from 'vue-router';

import Home from '@/views/Home';
import About from '@/views/About';
import Detail from '@/views/Detail';


Vue.use(VueRouter);

let router = new VueRouter({
    mode: 'history',

    scrollBehavior(to, from, savedPosition) {
        console.log(savedPosition);

        if (to.meta.isToSavedPosition && savedPosition) {
            // 调用的浏览器的历史记录
            return savedPosition;
        }

        return {
            x: 0,
            y: 0
        }
    },

    routes: [
        {
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/about',
            name: 'about',
            component: About
        },
        {
            path: '/view',
            name: 'view',
            component: Detail,
            meta: { isToSavedPosition: true}
        }
    ]
});

export default router;

在这里插入图片描述

参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a2.32
Branch: branch07

commit description:a2.32(example01-1——初步实现除了详情页,其他页面点击前进和后退都顶到头)

tag:a2.32

4.2 example02

通过以上这种方式 ,就可以判断当前页面后退的时候,到底是重置为0呢?还是保持原来的位置?

如果我们运用原生逻辑判断的方式,会十分的麻烦,这个时候就可以把信息记录在路由原元信息当中了,在路由中通过tofrom这些参数拿到对应自定义的元信息了,进行处理。

比如有很多的菜单,即页面当中必然有一些导航,这个时候我们会发现,我们有一种办法通过这种路由的方式去动态生成导航,这里有三个页面,我们动态生成三个导航。

4.2.1 example02-1

isNav,说明此页面到底加不加导航链接。

    routes: [
        {
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/about',
            name: 'about',
            component: About
        },
        {
            path: '/view',
            name: 'view',
            component: Detail,
            meta: { isToSavedPosition: true, isNav: true }
        }
    ]

app\src\views\Home.vue

<template>
    <div>
        <nav>
            <div v-for="nav of navs">
                <router-link :to="nav.path">{{nav.name}}</router-link>
                <span> | </span>
            </div>
        </nav>
        <hr>
        <ul>
            <li v-for="i of 100">{{i}}</li>
        </ul>
    </div>
</template>

<script>

    export default {
        name: "Home",

        data() {
            return {
                navs: []
            }
        },

        created() {
            console.log(this.$router);
            // this.$router.options.routes 所有路由的信息
            this.navs = this.$router.options.routes;
        }
    }
</script>

<style>
</style>

在这里插入图片描述

在这里插入图片描述

如果不希望动态生成 =>

meta: { isToSavedPosition: true, isNav: false }

然后在created中进行过滤

<template>
    <div>
        <nav>
            <div v-for="nav of navs">
                <router-link :to="nav.path">{{nav.name}}</router-link>
                <span> | </span>
            </div>
        </nav>
        <hr>
        <ul>
            <li v-for="i of 100">{{i}}</li>
        </ul>
    </div>
</template>

<script>

    export default {
        name: "Home",

        data() {
            return {
                navs: []
            }
        },

        created() {
            console.log(this.$router);
            // this.$router.options.routes 所有路由的信息
            // this.navs = this.$router.options.routes;
            this.navs = this.$router.options.routes.filter(route => {
                // 无meta标签
                if (route.meta === undefined) {
                    return true;
                }
                // 有meta标签 => 需要显示就显示
                if (route.meta.isNav === true) {
                    return true;
                }
            });
        }
    }
</script>

<style>
</style>

在这里插入图片描述

参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a2.33
Branch: branch07

commit description:a2.33(example02-1——动态生成子导航)

tag:a2.33

4.2.2 example02-2

有的时候name并不想显示英文,meta加一个中文属性。

meta这个元数据,其实存放与本质数据无关的旁观数据,就和我们的标签的自定义属性一样,主要挂载一些不太重要的数据。

    routes: [
        {
            path: '/',
            name: 'home',
            component: Home,
            meta: { navName: '首页' }
        },
        {
            path: '/about',
            name: 'about',
            component: About,
            meta: { navName: '关于我们' }
        },
        {
            path: '/view',
            name: 'view',
            component: Detail,
            meta: { isToSavedPosition: true, isNav: false, navName: '视图' }
        }
    ]

\app\src\views\Home.vue

<template>
    <div>
        <nav>
            <div v-for="nav of navs">
                <router-link :to="nav.path">{{nav.meta.navName}}</router-link>
                <span> | </span>
            </div>
        </nav>
        <hr>
        <ul>
            <li v-for="i of 100">{{i}}</li>
        </ul>
    </div>
</template>

<script>

    export default {
        name: "Home",

        data() {
            return {
                navs: []
            }
        },

        created() {
            console.log(this.$router);
            // this.$router.options.routes 所有路由的信息
            // this.navs = this.$router.options.routes;
            this.navs = this.$router.options.routes.filter(route => {
                // 无meta标签
                if (route.meta === undefined || route.meta.isNav === undefined) {
                    return true;
                }
                // 有meta标签 => 需要显示就显示
                if (route.meta.isNav === true) {
                    return true;
                }
            });
        }
    }
</script>

<style>
</style>

在这里插入图片描述

参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a2.34
Branch: branch07

commit description:a2.34(example02-2——动态生成子导航附加中文)

tag:a2.34

考虑到在blog中不好体现代码更改的位置,小迪才用github托管代码,大家可以查看github,看到详细版本修改过程,搭配博客学习。



(后续待补充)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值