路由介绍

image.png
映射表:路由器的功能就是储存ip地址和mac地址的关系,别人把数据发给你时,路由器查看数据的目标ip地址,然后找下自己记录的ip地址对应哪个mac地址,然后从这个mac地址对应的网线口上发出去。这个ip和mac地址的表就叫映射表。

前端路由:用户浏览器访问的 地址url 和 实际页面 的关系,就像ip和mac的关系,所以叫前端路由。访问特定的url地址,给你展现特定的页面或者数据。
image.png

1、后端路由(JSP)

image.png
image.png
image.png
SEO:搜索引擎优化,大部分搜索引擎,都是提前对某个网站的所有页面进行爬虫,获取上面的文本数据,比如一个物流公司的网站,公司介绍等等。

用户在搜索引擎上输入关键字搜索时,如搜索物流,搜索引擎就会去网页库里面找对应的关键字信息(物流),就会搜索到这家物流公司的某个页面带有物流字眼,会返回给用户这个网站的这个页面。

优化就是尽量让自己的页面关键字能被用户更好的搜索到,且搜索的结果排名更前。
image.png
另外学习成本提高,比如Java通过jsp开发,你除了需要了解HTML、css、JS,还得会Java、Jsp后端框架,数据库等技术,编辑器只能使用后端特定的编辑器。

2、前后端分离

image.png
路由还是在服务器上
image.png

3、单页面富应用SPA(前端路由)

image.png
由前端控制页面的url和组件的渲染,组件间的切换,无需像前后端分离那样切换页面就请求一次页面资源,导致浪费性能。
image.png
image.png

实现原理

两种方法,都能实现同样的效果

方法一:改变url的hash值,不会导致重新请求服务器资源

正常来说在浏览器输入地址访问,是会重新像服务器请求资源。

但是有个特性,如果地址后面加上#号,井号后面发生变化,是不会重新发送请求的,也不会导致页面刷新,因此可以通过js根据url的变化,来改变页面的内容
image.png
image.png image.png

方法二:Html5的history模式(window.history对象)

image.png
image.png
就是相当于浏览器上的返回和前进
image.png
image.png
pushState可以换成其他5种方法

====================

Vue router介绍

Vue router,是官方开发的,基于上面两种原理,给我们封装的一个插件,方便我们像上面一样使用,让页面的url变化,在不重新刷新界面的情况下变化页面的内容。

image.png

image.png

安装

方式一:vue-cli创建时自动安装

如果创建项目时,选择手动配置,然后选了Router,那么自动会安装并且应用到这个项目中去,自动生成router文件夹,和index.js。
image.png

方式二:手动安装

image.png
创建文件夹(建议)
image.png

引入和配置(见下使用)

使用

第一步:导入组件

见下第三步

第二步:配置路由映射: 组件和路径映射关系的routes数组;

见下第三步

第三步:创建路由对象,并且传入路由属性routes和history模式;

Vue Router 3.x(对应Vue 2.x)

router/index.js 文件解释

  1. //引入Vue、VueRouter和项目的入口主页
  2. import Vue from 'vue'
  3. import VueRouter from 'vue-router'
  4. // 第一步:导入组件
  5. import Home from '../views/Home.vue'
  6. //让Vue使用这个路由插件
  7. Vue.use(VueRouter)
  8. // 第二步:配置路由映射: 组件和路径映射关系的routes数组;
  9. //配置路由的映射,映射关系是一个数组,数组里面的对象,都是实际的页面,这些页面有路径,其他页面可以调用这里的页面
  10. const routes = [
  11. {
  12. //链接路径,路径指的是浏览器显示的路径,如http://localhost:8080/#/ 后面的
  13. path: '/',
  14. //路由名称,可选
  15. name: 'Home',
  16. //这个链接对应的组件模板
  17. component: Home
  18. },
  19. {
  20. path: '/about',
  21. //() => import('模板路径'),这样的方式称为懒加载,就是网页一开始不加载,用户点击后才加载,减少资源消耗,增加运行效率
  22. component: () => import('../views/About.vue')
  23. },
  24. {
  25. path: '/test',
  26. component: () => import('../views/Test.vue')
  27. },
  28. {
  29. path: '/test2',
  30. component: () => import('../views/Test2/')
  31. }
  32. ]
  33. // 第三步:创建路由对象,并且传入routes和history模式;
  34. //创建路由对象,对象的属性就是上面设置的参数
  35. const router = new VueRouter({
  36. routes
  37. })
  38. //导出路由对象,在main.js文件中,把这个挂载到Vue对象中
  39. export default router

Vue Router 4.x(对应Vue 3.x)

router/index.js

  1. //1、导入vue-router的基本功能
  2. import { createRouter, createWebHistory } from 'vue-router';
  3. // 第一步:导入组件
  4. //2、定义页面的文件路径
  5. const index = () => import('/@/views/index.vue')
  6. const home = () => import('/@/views/home/index.vue')
  7. const assetManagementIndex = () => import('/@/views/assetManagement/index.vue')
  8. const login = () => import('/@/views/login/index.vue')
  9. // 第二步:配置路由映射: 组件和路径映射关系的routes数组;
  10. // 3、把页面路径加入到路由,并定义访问页面的url路径
  11. const routes = [
  12. // 主页
  13. { path: '/', name: 'index', component: index,children: [
  14. { path: '/', redirect: { name: 'home' } }, //匹配所有其他404页面
  15. { path: '/assetManagement/index',name: 'HelloWorld', component: assetManagementIndex },
  16. { path: '/home',name: 'home', component: home },
  17. ] },
  18. // 登录页
  19. { path: '/login', name: 'login', component: login},
  20. { path: '/:pathMatch(.*)*', redirect: {name:'home'}},
  21. ]
  22. // 第三步:创建路由对象,并且传入routes和history模式;
  23. //4、创建路由
  24. const router = createRouter({
  25. history: createWebHistory(), //设置为没有#号的url路径
  26. routes, //routes:routes 的简写
  27. });
  28. // 导航守卫,每次发生跳转前,都会执行函数内代码
  29. router.beforeEach((to, from, next) => {
  30. let isLogin = false;
  31. // 判断是否登录,登录了就跳转到正常页面,没登录就跳转登录页
  32. if (to.name !== 'login' && !isLogin) {
  33. console.log(`跳转到登录页`)
  34. next({name:'login'})
  35. } else {
  36. next();
  37. }
  38. })
  39. //5、导出模块到全局
  40. export default router;
  41. //6、然后在 main.js 中,引入router
  42. //7、最后在 main.js 中.use(router) 让APP应用使用路由
  43. //使用
  44. //1、在要使用跳转的.vue文件,引入路由
  45. //import { useRouter } from "vue-router";
  46. //2、在setup()里面创建路由实例
  47. //const router = useRouter();
  48. //3、使用跳转
  49. //router.push("路径")

第四步:在对应的组件内使用路由页面和路由跳转

两个都是vueRouter内置组件,
是必要的,你配置映射的组件,会在这个标签里面显示
是非必要的,相当于是一个a标签,我们还有很多方法可以控制跳转
image.png

第五步:引入到main.js

image.pngVue 3

TS中配置

查看 https://www.yuque.com/yejielin/mypn47/qcd0at#yzbnk

====================

路由的属性 route

查看 Vue Router - 页面路由属性 route

路由跳转对象 router

查看 Vue Router - 路由跳转对象 router

====================

特性

标签属性

查看 Vue Router - 标签属性

路由模式(#号)

只要在router文件夹里面的index.js添加mode: ‘history’,就不会在浏览器链接上显示#号
Vue Router 3.x(对应Vue 2.x)

  1. const router = new VueRouter({
  2. //添加mode: 'history',要写在routes的前面
  3. mode: 'history',
  4. routes
  5. })
  6. export default router

Vue Router 4.x(对应Vue 3.x)
image.png

懒加载

查看Vue Router - 页面路由属性 route

动态路由

查看 Vue Router - 页面路由属性 route

嵌套路由

查看 https://www.yuque.com/yejielin/mypn47/dlefh4#oN3ej

动态添加/删除路由

使用场景

后台管理系统,都会有账号、角色以及对应的权限。

有一种方案是前端控制角色的权限,给角色动态添加路由,因此一开始const routes = [ ] 并不是一开始写死的。

如果写死,用户直接在浏览器输入/user 这样的路径,即便他没有显示这个菜单,也能进入(虽然这个也可以通过路由导航守卫解决)。

因此routes 一开始是空数组,前端用if判断角色,给不同角色添加不同的路由

添加一级路由

image.png

添加子级路由

如果想给某个路由添加子路由,需要先设置路由的名字,然后添加进来
image.png
这个被添加的(上图的HomeMoment.vue),也可以有自己的子路由,会一起跟着加进来

然后正常使用
image.png

删除路由

方式一:添加一个name相同的路由
image.png

方式二:通过removeRoute方法,传入路由的名称name属性
image.png
方式三:通过addRoute方法的返回值回调
image.png

检查路由是否存在

router.hasRoute( ):检查路由是否存在。
router.getRoutes( ):获取一个包含所有路由记录的数组。

父传递数据给子

有两种方式传递,区别在于路径不一样
params:/router/123/why
query:/router?id=123&userName=why

方法一:动态路由params

image.png
image.png

  1. <template>
  2. <router-link to="/user/zhangsan"></router-link>
  3. <!--to要用v-bind绑定属性,相当于路径是/user/abc-->
  4. <router-link :to="'/user/'+user"></router-link>
  5. <router-view></router-view>
  6. </template>
  7. <script>
  8. export default {
  9. name:'name',
  10. data(){
  11. return {
  12. //绑定router-link标签的to属性,添加一个变量,实现动态路由
  13. user:'abc'
  14. }
  15. }
  16. }
  17. </script>

子通过页面路由属性对象route的属性params 获取到{ id : abc }

route获取和使用可以查看 Vue Router - 页面路由属性 route

方法二:query类型

image.png
父组件
通过to里面的参数query,把对象传入子组件

  1. <router-link :to="{path:'/hi',query:{name:'abc',age:18}}">kk</router-link>
  2. <!--点击后,浏览器变为:locahost:80/hi?name=abc&age=18-->

父组件还可以通过父组件的变量,把值传入

  1. <template>
  2. <div>
  3. <router-link :to="{path:'/about/test2',query:{name:myName,age:31}}">Test2</router-link>
  4. <router-view />
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. data() {
  10. return {
  11. myName:"yjl"
  12. };
  13. }
  14. };
  15. </script>

子组件
子通过页面路由属性对象route的属性query获取到 {name:’abc’,age:18}

  1. <template>
  2. <div>
  3. {{ $route.query.name}}
  4. {{ $route.query.age}}
  5. </div>
  6. </template>

获取和使用可以查看 Vue Router - 页面路由属性 route

====================

导航守卫

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。

也就是根据跳转时拦截跳转,然后判断条件,来决定跳转还是取消跳转。

比如跳转时如果是登录页面,就清除cookie;如果跳转的页面没有对应的权限,就跳回主页等等。

完整导航触发

image.png
类似于导航的生命周期函数,基本的就是导航跳转前执行、跳转的组件加载完成后执行、跳转完成后执行。

一般用的多的就是beforeEach,其他用的少

全局守卫

全局的意思是,只要发生跳转行为,不管发生多少次,每次都会统一触发。

如跳转后修改网页的title;用于显示主页前验证是否登录,没登录就跳转到登录界面等。

全局守卫,要写在在router里面的index.js文件内。

  1. const router = new VueRouter({
  2. mode: 'history',
  3. linkActiveClass:"active",
  4. routes
  5. })
  6. //导航跳转前执行函数
  7. router.beforeEach((to,from,next)=>{
  8. console.log("beforeEach");
  9. //一定要调用next()方法,否则浏览器不会自动完成跳转
  10. next();
  11. });
  12. //跳转的组件加载完成后执行函数(所有组件内守卫和异步路由组件被解析之后)
  13. router.beforeResolve((to,from,next)=>{
  14. console.log("beforeResolve");
  15. //一定要调用next()方法,否则浏览器不会自动完成跳转
  16. next();
  17. })
  18. //跳转完成后执行函数,不会接受 next 函数也不会改变导航本身
  19. router.afterEach((to,from)=>{
  20. console.log("afterEach");
  21. })
  22. export default router

每个守卫方法参数(to,from,next)
image.png
image.png
默认导航:正常跳转,该去哪还是去哪;

路径地址:直接跳转这个路径地址,可以是路径字符串或者对象,类似于{ path : ‘ /user ‘ , query : { a:1 } }

next

image.png

组件内守卫

就是组件内,只要发生跳转,就会触发执行3种函数。

都需要调用next( ) 方法,否则跳转不了。

  1. <template>
  2. <div>123</div>
  3. </template>
  4. <script>
  5. export default {
  6. data() {
  7. return {};
  8. },
  9. beforeRouteEnter:function(to, from, next){
  10. // 跳转到这个组件前,执行函数
  11. // 不!能!获取组件实例 `this`,因为当守卫执行前,组件实例还没被创建
  12. console.log("组件beforeRouteEnter");
  13. next();
  14. },
  15. beforeRouteUpdate (to, from, next) {
  16. // 在当前路由改变,但是该组件被复用时调用
  17. // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
  18. // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
  19. // 可以访问组件实例 `this`
  20. console.log("组件beforeRouteUpdate");
  21. next();
  22. },
  23. beforeRouteLeave (to, from, next) {
  24. // 导航离开该组件的对应路由时调用
  25. // 通常用来禁止用户在还未保存修改前突然离开
  26. // 可以访问组件实例 `this`
  27. console.log("组件beforeRouteLeave");
  28. next();
  29. }
  30. };
  31. </script>

路由独享守卫

  1. const router = new VueRouter({
  2. routes: [
  3. {
  4. path: '/foo',
  5. component: Foo,
  6. beforeEnter: (to, from, next) => {
  7. // ...
  8. }
  9. }
  10. ]
  11. })

meta 元数据

router里面的index.js文件内,可以给每个页面添加元数据,后面路由时,可以调用to.matched[0].meta 或 from.matched[0].meta 方法来获取相应组件的元数据

  1. {
  2. path: '/Hello',
  3. name: 'Hello',
  4. //meta是元数据,描述数据的数据
  5. meta:{
  6. title:'abc'
  7. }

keep-alive 缓存页面

vue2

image.png
image.png

vue 3

查看 Vue Router - 标签属性

包含 include

排除name=Profile的组件,其他组件保留缓存,可以被缓存

排除 exclude

排除name=Profile的组件,其他组件保留缓存,这个组件频繁创建和销毁。
多个组件可以用逗号隔开,但不能加空格
image.png

激活、失去激活

image.png

滚动行为 scrollBehavior

使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。