前言
相信大家也是从我的路由初级篇那边过来的,没看的话也可以先从初级开始看,可以提高后续的理解能力
路由初级篇的链接
别的也就不多说了,直接开始
路由的主体构成
前言
之前的路由写法虽然可以使用但是会导致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})//全局路由守卫---先占位后续会讲解//导出 routerexport 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>
- 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生命周期钩子精细控制哪些组件应被缓存及缓存组件的状态管理。