目录
一、历史进程
1. 后端路由阶段
2. 前后端分离阶段
3. 单页面富应用(SPA)
二、路由跳转的方式
1. URL的hash
2. HTML5的History
3. 区别
三、Vue-Router基本使用
1. 概念
2. 安装
3. 路由的使用步骤
01 - 创建映射组件
02 - 创建路由对象
03 - 在 main.js 中导入
04 - 在App.vue文件中设置
05 - 效果
4. 路由的默认路径
5. 使用history模式
6. router路由的属性
7. notFound
01 - 路由设置
02 - 组件代码
03 - 效果
8. router-link
01 - to属性
02 - replace属性
03 - active-class属性
默认
设置
04 - exact-active-class属性
四、路由懒加载分包处理
1. 路由懒加载
2. 分包处理
五、动态路由
1. 设置路由
2. 跳转设置
3. 组件中获取值
4. 效果
六、路由嵌套
1. 子组件创建
2. 路由设置
3. 组件设置
4. 效果
5. exact-active-class属性
七、路由的编程式导航,代码的页面跳转
1. 简单使用
代码
效果
2. 跳转方式
01 - 通过 name 跳转并传递参数
设置
传递
获取
效果
缺点
02 - 通过 path 跳转并传递参数
设置
传递
获取
效果
3. 前进后退
back
forward
go
4. push | replace
01 - push
02 - replace
八、动态管理路由对象
1. 添加路由
01 - 添加顶层路由
02 - 添加次级路由
03 - 添加三级路由
2. 删除路由
01 - 方式一
02 - 方式二
03 - 方式三
3. 检查路由
4. 获取所有路由
九、路由导航守卫钩子
1. 全局的前置守卫
01 - 参数
02 - 返回值
03 - 登录守卫功能栗子
router.js代码
login组件代码
效果
2. 其他的导航守卫 导航守卫 | Vue Router
3. 完整的导航解析流程
路由的概念在软件工程中出现,最早是在后端路由中实现的 :
早期的网站开发整个HTML页面是由服务器来渲染的,服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示
多页面服务器如何处理 :
上面的这种操作, 就是后端路由 :
后端路由的缺点 :
前端渲染的理解 :
前后端分离阶段 :
单页面富应用阶段 :
history接口是HTML5新增的, 它有六种模式改变URL而不刷新页面
目前前端流行的三大框架, 都有自己的路由实现 :
Vue Router :
npm install vue-router
在根目录下创建router文件夹,并在其中创建index.js
// 1. 导入创建路由对象 和 创建hash对象
import { createRouter, createWebHashHistory } from 'vue-router';
// 2. 导入组件
import Home from '../views/Home.vue';
import About from '../views/About.vue';
// 3. 配置路由映射关系表
const routes = [
// 路径和组件映射起来
{ path: '/home', component: Home },
{ path: '/about', component: About }
];
// 4. 创建路由对象
const router = new createRouter({
// 5. 配置路由跳转模式,这里使用 hash 模式
history: createWebHashHistory(),
// 把映射表放入
routes
});
// 5. 导出
export default router;
import { createApp } from 'vue';
import App from './App.vue';
// 1. 导入路由对象
import router from './router';
// 2. 使用use调用一下
createApp(App).use(router).mount('#app');
router-link => 跳转链接
router-view => 组件显示的位置
App 页面
Home
About
以让路径默认跳到到首页
path配置的是根路径: / => redirect是重定向
const routes = [
// 默认显示的页面 => home
{ path: '/', redirect: '/home' },
{ path: '/home', component: Home },
{ path: '/about', component: About }
];
// 1. 导入创建路由对象
/**
* createWebHashHistory : hash模式
* createWebHistory : history模式
*/
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';
const routes = [
{ path: '/', redirect: '/home' },
{ path: '/home', component: Home },
{ path: '/about', component: About }
];
const router = new createRouter({
// 使用history模式
history: createWebHistory(),
routes
});
// 5. 导出
export default router;
const routes = [
{
path: '/',
redirect: '/home'
},
{
name: 'home',
path: '/home',
component: Home,
meth: {
name: 'coderstar',
age: 28
}
},
{
name: 'about',
path: '/about',
component: About
}
];
对于哪些没有匹配到的路由,通常会匹配到固定的某个页面
// 如果匹配到任何一个不存在的路径,就显示这个组件
{
name: 'notFound',
path: '/:pathMatch(.*)', // => 地址一样的显示出来 => abc/erfsdf/gsa/e
path: '/:pathMatch(.*)*', // => 如果遇到分级,会解析 / ,变成一个数组 => ['abc','erfsdf','gsa','e']
component: () => import('../views/NotFound.vue')
}
NotFound : 抱歉,出错了,未找到该页面
出错路径为 : {{ $route.params.pathMatch }}
router-link => 有很多属性可以配置
to : 是一个字符串,或者是一个对象
指定跳转到哪个组件
Home
Home
不设置的时候
使用的是 router.push() ,可以点击浏览器的返回,回到上一次记录页面
设置的时候
使用的是router.replace(),无法返回到上一次记录页面
Home
About
设置激活a元素后应用的class,默认是router-link-active
Home
About
链接精准激活时,应用于渲染的 的 class,默认是router-link-exact-active
ps : 精准定位路由,用于嵌套路由中
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载
const routes = [
{
path: '/',
redirect: '/home'
},
{
name: 'home',
path: '/home',
// 路由懒加载
component: () => import('../views/Home.vue'),
meth: {
name: 'coderstar',
age: 28
}
},
{
name: 'about',
path: '/about',
// 路由懒加载
component: () => import('../views/About.vue')
}
];
webpack从3.x开始支持对分包进行命名(chunk name)
const routes = [
{
path: '/',
redirect: '/home'
},
{
name: 'home',
path: '/home',
// 路由懒加载
component: () => import('../views/Home.vue'),
meth: {
name: 'coderstar',
age: 28
}
},
{
name: 'about',
path: '/about',
// 路由懒加载,可以顺便设置分包后的名称
component: () => import(/* webpackChunkName: 'about' */ '../views/About.vue')
}
];
很多时候需要将给定匹配模式的路由映射到同一个组件
{
name: 'user',
// 动态设定 id 和 name
path: '/user/:id/:name',
component: () => import('../views/User.vue')
}
User => 1
User => 2
我是用户user => {{ $route.params.id }} - {{ $route.params.name }}
路由嵌套 : 组件的内部可能有多个组件来回切换
const routes = [
{
path: '/',
redirect: '/home'
},
{
name: 'home',
path: '/home',
component: () => import('../views/Home.vue'),
meth: {
name: 'coderstar',
age: 28
},
// 配置子路由
children: [
{
// 配置重定向,默认进去 home组件 中的 A组件
path: '/home',
redirect: '/home/A'
},
{
// 注 : 这里不需要写全称 => /home/a
path: 'a',
component: () => import('../views/HomeA.vue')
},
{
// 注 : 这里不需要写全称 => /home/b
path: 'b',
component: () => import('../views/HomeB.vue')
}
]
},
{
name: 'about',
path: '/about',
component: () => import('../views/About.vue')
},
{
name: 'user',
path: '/user/:id/:name',
component: () => import('../views/User.vue')
},
{
name: 'notFound',
path: '/:pathMatch(.*)',
component: () => import('../views/NotFound.vue')
}
];
我是home组件
toA
toB
|
{
name: 'home', // 用name这个属性来跳转
path: '/home',
component: () => import('../views/Home.vue'),
meth: {
name: 'coderstar',
age: 28
},
children: [
{
path: '/home',
redirect: '/home/A'
},
{
path: 'a',
component: () => import('../views/HomeA.vue')
},
{
path: 'b',
component: () => import('../views/HomeB.vue')
}
]
},
{
name: 'about', // 用name这个属性来跳转
path: '/about',
component: () => import('../views/About.vue')
}
|
我是about组件
{{ $route.query }}
子路由的重定向路由会失效,看看上方home组件的即可知道
{
name: 'home',
path: '/home', // 用path这个属性来跳转
component: () => import('../views/Home.vue'),
meth: {
name: 'coderstar',
age: 28
},
children: [
{
path: '/home',
redirect: '/home/A'
},
{
path: 'a',
component: () => import('../views/HomeA.vue')
},
{
path: 'b',
component: () => import('../views/HomeB.vue')
}
]
},
{
name: 'about',
path: '/about', // 用path这个属性来跳转
component: () => import('../views/About.vue')
},
|
我是about组件
{{ $route.query }}
back => 想后回退
About: {{ $route.query }}
forward => 想前进步
About: {{ $route.query }}
某些情况下可能需要动态的来添加路由
根据用户不同的权限,注册不同的路由
// 添加顶层路由
let isAdmin = true;
if (isAdmin) {
router.addRoute({
name: 'admin',
path: '/admin',
component: () => import('../views/Admin.vue')
});
}
// 5. 导出
export default router;
// 添加次级路由
let isAdmin = true;
if (isAdmin) {
// 第一个参数传 父级的name
router.addRoute('home', {
name: 'home-a1',
path: 'a1', // 实际上是 /home/a1
component: () => import('../views/HomeA1.vue')
});
}
// 5. 导出
export default router;
let isAdmin = true;
if (isAdmin) {
router.addRoute('home', {
name: 'home-a1',
path: 'a1',
component: () => import('../views/HomeA1.vue')
});
// 三级路由,需要在 home-a1 中加上 router-view 哦
router.addRoute('home-a1', {
name: 'home-a2',
path: 'a2', // 实际上是 /home/a1/a2
component: () => import('../views/HomeA2.vue')
});
}
// 5. 导出
export default router;
添加一个name相同的路由
新添加的路由,会把之前同名的路由给覆盖掉,因为name属性是唯一的
router.addRoute({
name: 'home-a1',
path: 'a1', // '/a1'
component: () => import('../views/HomeA1.vue')
});
// 会覆盖掉上面的
router.addRoute({
name: 'home-a1',
path: 'a999999', // '/a999999'
component: () => import('../views/HomeA2.vue')
});
通过removeRoute方法,传入路由的名称
router.addRoute({
name: 'home-a1',
path: '/a1',
component: () => import('../views/HomeA1.vue')
});
// 删除路由
router.removeRoute('home-a1');
通过addRoute方法的返回值回调
// 1. 增加路由后,会有一个返回值方法
const removeA1 = router.addRoute({
name: 'home-a1',
path: '/a1',
component: () => import('../views/HomeA1.vue')
});
// 2. 调用该返回值方法,即可删除路由
removeA1();
router.hasRoute() => 检查路由是否存在
console.log(router.hasRoute('about')); // true
router.removeRoute('about');
console.log(router.hasRoute('about')); // false
router.getRoutes():获取一个包含所有路由记录的数组
console.log(router.getRoutes()); // 一个路由数组
vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航
全局的前置守卫 beforeEach 是在导航触发时会被回调的
进行任何的路由跳转之前, 传入的beforeEach中的函数都会被回调
// 路由导航首位
/**
* to : 去哪个路由
* from : 从哪里来
*/
// 1. 设定需要登录才能进的页面
const needLoginRoutePath = ['/about', '/user/222222/star'];
router.beforeEach((to, from) => {
// 2. 判断是否进入需要登录后才能进的页面
if (needLoginRoutePath.includes(to.path)) {
// 3. 获取登录状态
const token = sessionStorage.getItem('token');
// 4. 判断 => 如果没登录,跳转到登录页面
if (!token) {
// 01. 返回登录页面的路径即可
// return '/login';
// 02. 同时传递数据过去
return {
path: '/login',
query: {
toPath: to.path
}
};
}
}
});
// 5. 导出
export default router;
Login页面
账号 :
密码 :