Vue路由详解

本文详细介绍了VueRouter的基本概念,包括路由、组件、动态路由、前端与后端的区别,以及如何使用编程式和声明式导航、路由守卫和懒加载功能。还涵盖了路由参数的处理,如props和query的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本概念

  • 路由(Route): Vue Router 使用路由来管理 URL 和组件之间的映射关系。每个路由可以包含一个路径(path)和一个对应的组件(component)。

  • 路由器(Router): Vue Router 的实例,用于管理整个应用的路由。

  • 路由视图(RouterView): 用于显示匹配当前 URL 的组件的容器。通常情况下,一个 Vue 组件中只能包含一个 <router-view>,它会根据当前 URL 自动切换显示不同的组件。

前端路由与后端路由

后端路由

019f324726794e7e8d59acc08e85c99b.png

前端路由

52449b841ae543319e7af71287dd1986.png

基本使用 

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

    // 引入组件
    import home from "./home.vue";
    import about from "./about.vue";

    // 要告诉 vue 使用 vueRouter
    Vue.use(VueRouter);

    const routes = [
        {
            path:"/home",
            component: home
        },
        {
            path: "/about",
            component: about
        }
    ]

    var router =  new VueRouter({
        routes
    })
    export default router;

路由匹配

动态路由

应用实例:当我们去访问网站并登录成功后,它会显示 欢迎你,+ 你的名字。不同的用户登录, 只是显示“你的名字” 部分不同,其它部分是一样的

//router.js中

/*新增user路径,配置了动态的id*/

{

     path: "/user/:id",

     component: user

},

//组件中

<router-link to="/user/123">User123</router-link>

嵌套路由

在路由的设计上,首先进入到 home ,然后才能进入到phone, tablet, computer. Phone, tablet, compute 就相当于进入到了home的子元素。所以vue 提供了childrens 属性,它也是一组路由,相当于我们所写的routes。

 {
        path:"/home",
     // 下面这个属性也不少,因为,我们是先进入home页面,才能进入子路由
        component: home,
     // 子路由
        children: [
            {
                path: "phone",
                component: phone
            },
            {
                path: "tablet",
                component: tablet
            },
            {
                path: "computer",
                component: computer
            }
        ]
    },

路由导航

编程式导航

使用 router.pushrouter.replacerouter.go 方法来实现页面的跳转。

// 字符串(路径名称)
router.push('/home')

// 对象
router.push({path: '/home'})

// 命名的路由(传递参数)
router.push({name: 'user', params: {id: 123}})

// 带查询参数, 变成/user?name=zhangsan
router.push({path: '/user', query: {name: 'zhangsan'}})

 meta属性

在Vue路由(vue-router)中,meta 是一种用来描述路由元信息的属性。路由元信息是指在路由配置中,可以为每个路由添加一些额外的数据或配置,这些数据或配置可以用来控制路由的行为或在路由之间共享数据。meta 属性就是用来定义这些路由元信息的。

meta 的作用
  • 动态设置页面标题:可以在 meta 中指定页面标题,并在路由守卫中动态设置 document.title
  • 权限控制:在 meta 中指定允许访问的角色,实现不同用户角色的权限管理。
  • 页面缓存:通过 meta 属性中的某个字段(如 keepAlive)来控制页面是否应该被缓存。
  • 页面过渡效果:在 meta 中指定页面过渡效果,并在主组件中使用 <transition> 标签来实现。
  • 加载指示器:通过 meta 属性控制路由切换时是否显示加载指示器。
具体案例

以下是一个使用 meta 属性的具体案例,展示了如何在Vue路由中配置和使用 meta 来设置页面标题和进行权限控制。

设置页面标题
const routes = [  
  {  
    path: '/home',  
    name: 'Home',  
    component: () => import('@/views/Home'),  
    meta: {  
      title: 'Home Page'  
    }  
  },  
  {  
    path: '/about',  
    name: 'About',  
    component: () => import('@/views/About'),  
    meta: {  
      title: 'About Us'  
    }  
  }  
];  
  
router.beforeEach((to, from, next) => {  
  if (to.meta.title) {  
    document.title = to.meta.title;  
  }  
  next();  
});

在这个案例中,我们为每个路由对象添加了一个 meta 属性,并在其中设置了 title 字段。然后,在全局前置守卫 beforeEach 中,我们检查即将进入的路由的 meta 属性中是否有 title 字段,如果有,则将其设置为页面的标题。

权限控制
const routes = [  
  {  
    path: '/admin',  
    name: 'Admin',  
    component: () => import('@/views/Admin'),  
    meta: {  
      requiresAuth: true,  
      roles: ['admin']  
    }  
  },  
  {  
    path: '/user',  
    name: 'User',  
    component: () => import('@/views/User'),  
    meta: {  
      requiresAuth: true,  
      roles: ['user', 'admin']  
    }  
  }  
];  
  
function getUserRole() {  
  return localStorage.getItem('userRole');  
}  
  
router.beforeEach((to, from, next) => {  
  if (to.matched.some(record => record.meta.requiresAuth)) {  
    const userRole = getUserRole();  
    if (!userRole) {  
      next({ path: '/login' });  
    } else if (to.meta.roles && to.meta.roles.indexOf(userRole) === -1) {  
      next({ path: '/unauthorized' });  
    } else {  
      next();  
    }  
  } else {  
    next();  
  }  
});

 在这个案例中,我们为每个需要认证的路由设置了 requiresAuth 和 roles 字段。在全局前置守卫中,我们首先检查即将进入的路由是否需要认证(即 requiresAuth 是否为 true)。如果需要认证,我们再检查用户角色是否匹配。如果不匹配或用户未登录,则重定向到相应的页面(如登录页面或未授权页面)。

声明式导航

使用 <router-link> 组件来生成跳转链接。

导航守卫

Vue Router 提供了导航守卫(Navigation Guards),允许你在路由发生变化时执行一些逻辑,比如在进入页面之前进行身份验证,或在离开页面时进行确认操作。

全局钩子函数(beforeEach、afterEach)

  • 全局前置守卫: router.beforeEach
  • 全局后置钩子: router.afterEach

路由独享的守卫: 在路由配置中直接定义 beforeEnter

组件内钩子函数(beforeRouterEnter、beforeRouterUpdate、beforeRouterLeave)

在Vue Router的全局前置守卫(beforeEach)中,tofromnext是三个非常重要的参数,它们分别代表了即将进入的目标路由信息、当前导航正要离开的路由信息,以及一个用于解决守卫钩子的函数。下面是对这三个参数的详细解析:

1. to

  • 类型Route
  • 描述:即将要进入的目标路由对象的信息。
  • 属性to 对象是一个路由信息对象,包含了目标路由的多个属性,如 pathqueryparamshashfullPathmatchedname 和 meta 等。你可以通过这些属性来获取目标路由的详细信息,或者基于这些信息来做出路由守卫的决策。

2. from

  • 类型Route
  • 描述:当前导航正要离开的路由对象的信息。
  • 属性:与 to 对象类似,from 对象也包含了当前路由的多个属性。在路由守卫中,from 对象通常用于与 to 对象进行比较,以决定是否需要执行某些操作(如重定向、警告等)。

3. next

  • 类型Function
  • 描述next 函数是必须调用的,用来解决守卫钩子。否则,整个路由流程都会被挂起。
  • 参数
    • 无参数:直接调用 next() 会将控制权交给下一个守卫(如果有的话),或者如果没有守卫了就执行路由的进入守卫和组件内的更新守卫(beforeEnter 和 beforeRouteUpdate),然后解析异步组件,最后实例化并渲染新的组件。
    • 错误:next(error)(2.4.0+)可以传入一个错误给 router.onError() 注册的回调。
    • 路径:next('/') 或者 next({ path: '/' }):直接跳转到另一个路由,中断当前导航。
    • 布尔值:next(false) 中断当前路由的解析流程,即阻止路由跳转。
    • 路由对象:next({ ... }) 或者 next(to):与 router.push 或 router.replace 类似,可以跳转到另一个路由,但是当前导航被中断,且 from 路由对应的组件会被销毁,to 路由对应的组件会被实例化并渲染。
router.beforeEach((to, from, next) => {  
  // 检查目标路由是否需要认证  
  if (to.matched.some(record => record.meta.requiresAuth)) {  
    // 假设有一个获取用户认证状态的函数  
    if (!isAuthenticated()) {  
      // 用户未认证,重定向到登录页面  
      next({  
        path: '/login',  
        query: { redirect: to.fullPath } // 将目标路由的路径作为参数,以便登录后重定向回去  
      });  
    } else {  
      // 用户已认证,继续执行后续逻辑  
      next();  
    }  
  } else {  
    // 目标路由不需要认证,直接通过  
    next();  
  }  
});

to.matched.some(record => record.meta.requiresAuth)这行代码的作用是:检查即将进入的目标路由(及其所有嵌套的子路由)中,是否有任何一个路由片段需要认证(即其meta属性中包含requiresAuth: true)。

  • 如果至少有一个路由片段需要认证,且当前用户未通过认证,则可以在全局前置守卫中进行相应的处理,如重定向到登录页面。
  • 如果没有路由片段需要认证,或者用户已经通过认证,则可以继续执行后续的路由逻辑。

03ff5cadeb7d41b9b16c354f931b2e69.png

eb774a52d70c4c1aafa63f7f4632371e.png

路由独享的钩子函数beforeEneter应用:(路由进入前想要执行的任务业务)

在Vue.js中,你可以使用路由的懒加载功能来提前预加载其他页面的业务。懒加载允许你按需加载页面组件,这意味着当用户导航到某个页面时才会加载该页面的相关代码。

const router = new VueRouter({
  routes: [
    {
      path: '/other-page',
      component: () => import('./OtherPage.vue'),
      // 在进入other-page路由之前预加载其他页面的业务逻辑
      beforeEnter(to, from, next) {
        // 执行预加载的业务逻辑
        preloadOtherPageData().then(() => {
          next();
        });
      }
    }
  ]
});

// 模拟预加载其他页面的业务逻辑
function preloadOtherPageData() {
  return new Promise((resolve, reject) => {
    // 执行一些异步操作,例如加载数据
    // 在这个示例中,我们简单地使用setTimeout来模拟异步操作
    setTimeout(() => {
      console.log('Preloading other page data...');
      resolve();
    }, 1000); // 模拟加载时间
  });
}

组件内的钩子函数

beforeRouteEnter因为触发的时候vue实例还没有创建,所以这个钩子函数中不能使用this,而beforeRouteUpdate和beforeRouteLeave都是可以访问到实例的,因为当这两个函数触发的时候实例都已经被创建了;

路由参数

props路径传参

//组件中
const user_com = {
   // 使用props接收路由参数
    props: ["id"],
    template: '< h1>User {{ id }}组件</h1>'
};
//路由中
var router = new VueRouter({
    routes: [
        // 动态参数, 以冒号开头
        {
            path: '/user/:id', 
            component: user_com,
            // 如果props被设置为true, route.params将会被设置为组件属性
            props: true,    
        },
    ],
});

Props值为函数类型:id以函数形式传递,若以路径参数传递无效!

onst user_com = {
 // 使用props接收路由参数
    props: ["id", "name", "age"],
    template: `
    <div>
        <h1>User {{ id }}组件</h1>
        <h2>{{name}} ======= {{age}}</h2>
    </div>`
    
};
var router = new VueRouter({
   routes: [
        {
            path: '/user/:id', 
            component: user_com,
            // 给props定义一个箭头函数
            props: route => ({
                name: "张三",
                age: 18,
                // 获取id值
                id: route.params.id
            })
        },
    ],
});

params参数与query参数

params参数传递

     由于动态路由也是传递params的,所以在 this.$router.push() 方法中path不能和params一起使用,否则params将无效。需要用name来指定页面【编程式,路由命名name+params】

query参数传递

【声明式/编程式,query+path/name皆可】

1.query传递显示参数,传递不显示参数,params相对于query来说较安全一点

2.query传值页面刷新数据还在,而params传值页面刷新数据消失

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GISer_Jinger

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值