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