vue-router(进阶版)

前言

相信大家也是从我的路由初级篇那边过来的,没看的话也可以先从初级开始看,可以提高后续的理解能力

路由初级篇的链接
别的也就不多说了,直接开始

路由的主体构成

前言

之前的路由写法虽然可以使用但是会导致main.js过于臃肿,所以后续基本不会再这么使用了,

初始化路由

创建router文件夹并初始化index.js文件

	---------router/index.js--------------------
import Vue from "vue";
import Router from 'vue-router';
//导入路由组件
import Home from "@/pages/home"
import Login from '@/pages/login'
//注册路由
	Vue.use(Router);
//对路由组件进行2配置
	let routes[
		 {path: "/",name: 'home',component: Main,}, 
	    {path: "/login", name: "login", component: Login}
	]
//创建一个 Router的实例
	const router = new Router({
	  routes
	})
	//全局路由守卫---先占位后续会讲解
	//导出 router
	export default router;

进入到入口文件main.js进行配置

----------------------main.js---------------------
//导入刚才创建的router文件下面的index.js文件
import router from './router'
//将router挂载到vue实例上
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

路由的初始化基本完成了,下面就开始一一对其分析

router文件的配置

routes的配置

let routes[
{path: “/”,name: ‘home’,component: Main,},
{path: “/login”, name: “login”, component: Login}
]

从上面可以看到routes其实是个数组,其中里面的每一个对象就是一个路由组件的配置

路由配置项

每个路由对象至少需要一个 path 和一个 component。

1. path

  • 类型: string

  • 必填: 是

  • 说明: 定义路由的匹配路径。可以包含动态片段、查询参数等。

  • 写法

/users:匹配直接访问 /users 的 URL。
/users/:id:匹配 /users/123 或 /users/john 等带有动态参数 id 的 URL。
/articles?category=:category:带有可选查询参数 category。

2. component

  • 类型: function | Object | Promise
  • 说明: 指定当路由被匹配时应渲染的 Vue 组件。可以是:
    引用已注册的全局组件或局部组件的函数。
    一个异步加载组件的返回 Promise 的工厂函数(使用 import() 动态导入)。
    一个通过 defineAsyncComponent 创建的异步组件对象。
  • 写法

1.使用已注册的组件
component: :Login
2.进行懒加载处理,使用时加载
component:: () => import(‘@/views/login/index’)

3. name

  • 类型: string
  • 必填: 否
  • 说明: 为路由规则赋予一个名称,便于通过名称进行编程式导航和在 中使用 to="{ name: ‘routeName’ }"以及编程式导航使用。

4. redirect

  • 类型: string | Object | Function
  • 说明: 路由重定向
    包含 path 或 name 及可选 query 的对象。
    返回重定向信息的函数,接收当前路由作为参数。
  • 写法
  {path: "/",redirect: '/home', }

5. alias

  • 类型: string | Array
  • 说明: 为当前路由提供一个或多个别名,访问别名时会展示与原路由相同的组件内容。

6. meta

  • 类型: Object
  • 说明: 用于存储与路由相关的元数据,可以包含任意自定义信息,常用于权限控制、界面布局调整、路由过渡动画设置等。例如:

meta: { requiresAuth: true } 表示该路由需要用户登录后才能访问。
meta: { title: ‘用户列表’,breadcrumb: ‘用户管理’ } 为页面提供额外信息。

7. props

  • 类型: boolean | Object | Function
  • 说明: 控制如何将路由参数注入到目标组件作为 props参数。可以是:
    true:直接将 $route 对象作为 prop 传递给组件。
    Object:定义从 $route 对象到组件 prop 的映射规则。
    Function:接收 $route 对象并返回 prop 对象。
  • 写法:
    1.第一种写法 props值为对象
---------------router/index.js-----------------------
{
        path:'login',
        component: Login,
// props对象中所有的key-value的组合最终都会通过props传给Login组件
        props:{
            id: '888',
            title: '你好啊'
        }
    }

2. 第二种写法:props值为布尔值

---------------router/index.js-----------------------
{
  	path:'login',
    component: Login,
    path:'login/:id/:title', //使用占位符声明接收params参数
    // 第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Login组件
    props: true
}
---------------Home.vue-----------------------
 <router-link :to="{
    path:'login',
    params: {
      id: item.id,
      title: item.title
    }
  }">跳转到登录页面</router-link>

3.第三种写法 props值为函数

{
   path:'login',
    component: Login,
    path:'login/:id/:title', //使用占位符声明接收params参数
    // 第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
    // props函数会自动调用并提供一个$route参数 可以通过$route来获取想要的数据传递给组件
    props($route) {
        return {
            id: $route.params.id,
            title: $route.params.title,
            // 还可以返回一些别的数据
            a: 1,
            b: "hello"
        }
    }
}

总结::不管使用哪种写法,接受参数的时候都是在路由对应的组件用props参数接收

8. children

  • 类型: Array
  • 说明: 嵌套路由配置,用于定义子路由。子路由的 path 是相对于父路由的 path 的
  • 写法:
  {
      path: "/",
      redirect: '/home',
      component: Main,
      children: [
        { path: "home", name: "home", component: Home },
   }

9. caseSensitive (3.1+)

  • 类型: boolean - 默认值: false
  • 说明: 指定路径匹配是否区分大小写。

路由实例的配置

mode:

定义路由模式。
默认为 hash,表示使用 URL 的 hash 部分。
另一个选项是 history,它使用 HTML5 History API (需要后端配置支持)。
例如:

const router = new VueRouter({
  mode: 'history',
  routes // (缩写) 相当于 routes: routes
})`

有兴趣了解hash模式和history模式的区别可以看下面的链接我对这个有详细的分析
链接: hash模式和history模式

base:

定义应用的基路径。例如,如果你的应用部署在一个子目录下,你可能需要设置这个选项。
默认为 /。

linkActiveClass:

模糊匹配

含被调用该路径都会被调用
定义 组件在导航到对应路由时应用的 CSS 类。
默认为 ‘router-link-active’。
路由激活时的样式

linkActiveClass:'自定义类名',
linkExactActiveClass:'自定义类名'

linkExactActiveClass:

精确匹配

当 的 to 属性与当前路由完全匹配时应用的 CSS 类。
默认为 ‘router-link-exact-active’。

scrollBehavior:

定义在导航触发时如何滚动页面。
使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置
这是一个函数,接受 to 和 from 路由对象。savedPosition参数就是当前页面滚动条的参数,它应该返回一个滚动位置对象,例如 { x: number, y: number }。

scrollBehavior(to, from, savedPosition) {
  return { x: 0, y: 0 }; // 滚动到页面顶部
}

parseQuery 和 stringifyQuery:

描述:
自定义查询字符串的解析和序列化逻辑。这两个函数分别用于处理URL中的查询参数。在某些情况下,如果需要处理非标准格式的查询字符串,或者使用自定义查询参数编码方案,可以替换这两个函数。

fallback:

当 mode 设置为 history 时,定义在浏览器不支持 HTML5 History API 时使用的回退模式。
默认为 true,表示回退到 hash 模式。

到此也基本介绍完成了,下面就开始介绍用法2了

导航方式

声明式导航

定义:

声明式导航是指在 Vue 组件的模板(template)中,通过使用 组件来创建导航链接。这些链接与普通的 HTML a 标签类似,但它们是专门设计用于与 Vue Router 集成,能够自动处理基于路由的导航。

常用属性

1. to --------必填属性
作用:定义目标路由的路径或名称,以及可能的参数和查询。
类型:string | Location
写法:

第一种写法:直接使用path路径
    <router-link to="/">Home</router-link>
第二种写法:命名路由,可以使用params传值
    <router-link to="{ name: 'user', params: { id: userId } }">User</router-link>
  1. replace
    类型:boolean

默认值:false

作用:如果设置为 true,点击链接时将以 replaceState 方式更新浏览器历史记录,即替换当前历史条目而不是添加一个新的条目。这样,点击浏览器的后退按钮不会返回到这个被替换的路由。

示例:

<router-link :to="{ name: 'profile' }" replace>Replace Current Route</router-link>

还有其他属性,但是这两个是最常用的,如果各位要深入了解的话,我单独写了一篇博客
router-link 的属性介绍

编程式导航

定义:

编程式导航是指在 Vue 组件的 JavaScript 部分(通常是 methods 或其他事件处理器中)通过调用 this.$router 对象上的方法来直接控制路由的切换。这种方式提供了更为灵活和精细的导航控制。

特点:

细粒度控制:可以在业务逻辑中根据条件判断、异步操作结果等灵活决定何时触发导航。
非阻塞性:可以配合 Promise 或 async/await 进行异步导航,例如等待用户确认或数据加载完成后再进行跳转。
多种导航操作:除了基本的跳转,还支持替换当前历史记录(replace())、后退或前进指定步数(go(n))等。
主要方法:
1.push(location):将新的路由条目推入浏览器历史记录,相当于用户点击链接进行导航。
2.replace(location):替换当前路由条目而不添加新记录到历史栈,用户点击后退按钮不会返回被替换的路由。
3.go(n):在浏览历史中向前或向后移动 n 步,正数表示前进,负数表示后退。

路由守卫

全局路由守卫

前置路由守卫

全局前置守卫 (router.beforeEach):
位置:在src/router/index.js文件中配置。
作用:对任何路由跳转(包括首次加载、手动导航、编程式导航)进行统一拦截。
示例代码:

  const router = new VueRouter({ /* ... */ });
   router.beforeEach((to, from, next) => {
     // 检查是否已登录(这里仅作为示例,实际应用中可能涉及更复杂的逻辑)
     if (!isAuthenticated) {
       // 未登录,重定向到登录页
       next('/login');
     } else {
       // 已登录,允许继续访问目标路由
       next();
     }
   });

后置路由守卫

全局后置钩子 (router.afterEach):
位置:同样在src/router/index.js文件中配置。
作用:在每次路由切换成功后执行,通常用于更新页面标题、埋点统计、页面缓存清理等工作,不涉及阻断路由访问。
示例代码:

  router.afterEach((to, from) => {
     document.title = to.meta.title || 'Default Title';
     // 或者进行其他通用的后处理操作
   });

路由独享守卫(beforeEnter)

位置:在定义路由配置对象时,直接在目标路由的配置内设置。
作用:仅对特定路由生效,执行特定的权限检查或其他业务逻辑。
示例代码:

 const routes = [
     {
       path: '/admin',
       component: AdminPanel,
       beforeEnter: (to, from, next) => {
         if (!isAdminUser) {
           next('/forbidden');
         } else {
           next();
         }
       },
       meta: { title: 'Admin Panel' }
     },
     // 其他路由...
   ];

组件路由守卫

位置:在路由组件内部编写。
分类:
beforeRouteEnter: 在进入路由前调用,不能访问当前组件实例(this不可用),但可以通过回调函数传递给next方法的数据访问。
beforeRouteUpdate: 路由参数变化时(路径相同而参数不同)调用,可以访问当前组件实例。
beforeRouteLeave: 离开当前路由时调用,可以访问当前组件实例。
示例代码(以beforeRouteEnter为例):

   export default {
     data() {
       return { articleId: null };
     },
     beforeRouteEnter(to, from, next) {
       // 获取文章ID并异步加载数据
       fetchArticle(to.params.articleId)
         .then(article => {
           next(vm => {
             // 将数据注入到组件实例
             vm.article = article;
           });
         })
         .catch(() => next('/error'));
     }
   };

总结:,通过合理运用全局守卫、路由独享守卫和组件内守卫,可以实现对Vue应用路由访问的精细化控制,确保用户只能在满足特定条件(如身份验证、权限检查等)的情况下访问相应的页面。

路由动画

-----------App.vue-------------------
<template>
  <div id="app">
    <!-- 其他布局元素 -->

    <!-- 单个路由视图过渡动画 -->
    <transition name="fade" mode="out-in">
      <router-view></router-view>
    </transition>

    <!-- 或者,如果需要对多个视图同时切换应用动画 -->
    <!-- <transition-group name="slide" tag="div" mode="out-in"> -->
    <!--   <router-view v-slot="{ Component }" :key="Component.name"> -->
    <!--     <component :is="Component"></component> -->
    <!--   </router-view> -->
    <!-- </transition-group> -->
  </div>
</template>
-----------App.vue/css-------------------
/* 淡入淡出动画 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

/* 滑动动画 */
.slide-enter-active,
.slide-leave-active {
  transition: transform 0.5s ease;
}

.slide-enter-from,
.slide-leave-to {
  transform: translateX(100%);
}

使用动态CSS类和过渡模式

动态CSS类:Vue Router会自动为处于过渡状态的元素添加相应的CSS类,如fade-enter-active、fade-enter-from等,对应着动画的不同阶段。这些类名基于你在组件上指定的name属性(如fade或slide)。

过渡模式:mode属性可设置为in-out(新元素先进行过渡,完成后再移除旧元素)、out-in(旧元素先移除,完成后再进行新元素的过渡)等,以控制过渡顺序。例如上述示例中使用了out-in模式,确保当前视图完全淡出后再淡入下一个视图。

进阶:自定义过渡组件与JavaScript过渡

除了使用CSS过渡和动画,还可以通过自定义过渡组件或直接在JavaScript中使用组件的内置钩子(如before-enter、enter、after-enter等)来精细控制过渡过程。这种情况下,可以利用Vue的组件的@before-enter、@enter等事件以及对应的v-bind:css="false"来禁用默认的CSS过渡,自行编写JavaScript逻辑来驱动动画。

嵌套路由动画

对于嵌套路由,可以在嵌套的上同样应用上述方法,为子路由之间的切换添加动画效果。只需在相应层级的组件中包裹并配置动画即可。

总之,通过结合Vue Router与Vue的过渡系统,可以轻松地为路由切换添加各种动画效果,增强应用的视觉表现力。只需在合适的位置使用或组件,配合相应的CSS动画或JavaScript钩子函数,即可实现丰富的过渡效果。

路由优化

懒加载(异步加载)路由组件

对于大型应用,将所有路由组件一次性打包会导致初始加载时间过长。通过使用动态import语法或Webpack的require.ensure(适用于老版本Webpack)实现路由组件的懒加载,可以显著减少首次加载时的资源大小,按需加载所需组件。

// 使用动态import语法(推荐)
const routes = [
  {
    path: '/about',
    component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),
  },
  // 其他路由...
];

预加载/预渲染未来可能访问的路由

对于预期用户可能会访问的路由,可以在后台提前加载其相关资源,以减少用户实际访问时的等待时间。Vue Router提供了router.prefetch方法和标签两种方式来实现预加载。

// 使用 router.prefetch 方法
router.prefetch('/future-route');

// 或者在HTML模板中使用<link rel="prefetch">标签
<!-- 预加载未来可能访问的路由组件 -->
<link rel="prefetch" href="/_webpack_entry_/future-route.js">

使用keep-alive组件缓存路由组件

对于频繁切换且数据更新不频繁的路由组件,可以使用组件进行缓存,避免每次切换时重新渲染,提高页面切换速度和用户体验。

<keep-alive>
  <router-view></router-view>
</keep-alive>

同时,可以结合include、exclude属性或activated、deactivated生命周期钩子精细控制哪些组件应被缓存及缓存组件的状态管理。

  • 32
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

明日筑梦师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值