路由介绍

映射表:路由器的功能就是储存ip地址和mac地址的关系,别人把数据发给你时,路由器查看数据的目标ip地址,然后找下自己记录的ip地址对应哪个mac地址,然后从这个mac地址对应的网线口上发出去。这个ip和mac地址的表就叫映射表。
前端路由:用户浏览器访问的 地址url 和 实际页面 的关系,就像ip和mac的关系,所以叫前端路由。访问特定的url地址,给你展现特定的页面或者数据。
1、后端路由(JSP)



SEO:搜索引擎优化,大部分搜索引擎,都是提前对某个网站的所有页面进行爬虫,获取上面的文本数据,比如一个物流公司的网站,公司介绍等等。
用户在搜索引擎上输入关键字搜索时,如搜索物流,搜索引擎就会去网页库里面找对应的关键字信息(物流),就会搜索到这家物流公司的某个页面带有物流字眼,会返回给用户这个网站的这个页面。
优化就是尽量让自己的页面关键字能被用户更好的搜索到,且搜索的结果排名更前。
另外学习成本提高,比如Java通过jsp开发,你除了需要了解HTML、css、JS,还得会Java、Jsp后端框架,数据库等技术,编辑器只能使用后端特定的编辑器。
2、前后端分离

路由还是在服务器上
3、单页面富应用SPA(前端路由)

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

实现原理
两种方法,都能实现同样的效果
方法一:改变url的hash值,不会导致重新请求服务器资源
正常来说在浏览器输入地址访问,是会重新像服务器请求资源。
但是有个特性,如果地址后面加上#号,井号后面发生变化,是不会重新发送请求的,也不会导致页面刷新,因此可以通过js根据url的变化,来改变页面的内容

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


就是相当于浏览器上的返回和前进

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


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

创建文件夹(建议)
引入和配置(见下使用)
使用
第一步:导入组件
见下第三步
第二步:配置路由映射: 组件和路径映射关系的routes数组;
见下第三步
第三步:创建路由对象,并且传入路由属性routes和history模式;
Vue Router 3.x(对应Vue 2.x)
router/index.js 文件解释
//引入Vue、VueRouter和项目的入口主页import Vue from 'vue'import VueRouter from 'vue-router'// 第一步:导入组件import Home from '../views/Home.vue'//让Vue使用这个路由插件Vue.use(VueRouter)// 第二步:配置路由映射: 组件和路径映射关系的routes数组;//配置路由的映射,映射关系是一个数组,数组里面的对象,都是实际的页面,这些页面有路径,其他页面可以调用这里的页面const routes = [{//链接路径,路径指的是浏览器显示的路径,如http://localhost:8080/#/ 后面的path: '/',//路由名称,可选name: 'Home',//这个链接对应的组件模板component: Home},{path: '/about',//() => import('模板路径'),这样的方式称为懒加载,就是网页一开始不加载,用户点击后才加载,减少资源消耗,增加运行效率component: () => import('../views/About.vue')},{path: '/test',component: () => import('../views/Test.vue')},{path: '/test2',component: () => import('../views/Test2/')}]// 第三步:创建路由对象,并且传入routes和history模式;//创建路由对象,对象的属性就是上面设置的参数const router = new VueRouter({routes})//导出路由对象,在main.js文件中,把这个挂载到Vue对象中export default router
Vue Router 4.x(对应Vue 3.x)
router/index.js
//1、导入vue-router的基本功能import { createRouter, createWebHistory } from 'vue-router';// 第一步:导入组件//2、定义页面的文件路径const index = () => import('/@/views/index.vue')const home = () => import('/@/views/home/index.vue')const assetManagementIndex = () => import('/@/views/assetManagement/index.vue')const login = () => import('/@/views/login/index.vue')// 第二步:配置路由映射: 组件和路径映射关系的routes数组;// 3、把页面路径加入到路由,并定义访问页面的url路径const routes = [// 主页{ path: '/', name: 'index', component: index,children: [{ path: '/', redirect: { name: 'home' } }, //匹配所有其他404页面{ path: '/assetManagement/index',name: 'HelloWorld', component: assetManagementIndex },{ path: '/home',name: 'home', component: home },] },// 登录页{ path: '/login', name: 'login', component: login},{ path: '/:pathMatch(.*)*', redirect: {name:'home'}},]// 第三步:创建路由对象,并且传入routes和history模式;//4、创建路由const router = createRouter({history: createWebHistory(), //设置为没有#号的url路径routes, //routes:routes 的简写});// 导航守卫,每次发生跳转前,都会执行函数内代码router.beforeEach((to, from, next) => {let isLogin = false;// 判断是否登录,登录了就跳转到正常页面,没登录就跳转登录页if (to.name !== 'login' && !isLogin) {console.log(`跳转到登录页`)next({name:'login'})} else {next();}})//5、导出模块到全局export default router;//6、然后在 main.js 中,引入router//7、最后在 main.js 中.use(router) 让APP应用使用路由//使用//1、在要使用跳转的.vue文件,引入路由//import { useRouter } from "vue-router";//2、在setup()里面创建路由实例//const router = useRouter();//3、使用跳转//router.push("路径")
第四步:在对应的组件内使用路由页面和路由跳转;
两个都是vueRouter内置组件,
第五步:引入到main.js
Vue 3
TS中配置
查看 https://www.yuque.com/yejielin/mypn47/qcd0at#yzbnk
====================
路由的属性 route
路由跳转对象 router
====================
特性
标签属性
路由模式(#号)
只要在router文件夹里面的index.js添加mode: ‘history’,就不会在浏览器链接上显示#号
Vue Router 3.x(对应Vue 2.x)
const router = new VueRouter({//添加mode: 'history',要写在routes的前面mode: 'history',routes})export default router
Vue Router 4.x(对应Vue 3.x)
懒加载
动态路由
嵌套路由
查看 https://www.yuque.com/yejielin/mypn47/dlefh4#oN3ej
动态添加/删除路由
使用场景
后台管理系统,都会有账号、角色以及对应的权限。
有一种方案是前端控制角色的权限,给角色动态添加路由,因此一开始const routes = [ ] 并不是一开始写死的。
如果写死,用户直接在浏览器输入/user 这样的路径,即便他没有显示这个菜单,也能进入(虽然这个也可以通过路由导航守卫解决)。
因此routes 一开始是空数组,前端用if判断角色,给不同角色添加不同的路由
添加一级路由
添加子级路由
如果想给某个路由添加子路由,需要先设置路由的名字,然后添加进来
这个被添加的(上图的HomeMoment.vue),也可以有自己的子路由,会一起跟着加进来
然后正常使用
删除路由
方式一:添加一个name相同的路由
方式二:通过removeRoute方法,传入路由的名称name属性
方式三:通过addRoute方法的返回值回调
检查路由是否存在
router.hasRoute( ):检查路由是否存在。
router.getRoutes( ):获取一个包含所有路由记录的数组。
父传递数据给子
有两种方式传递,区别在于路径不一样
params:/router/123/why
query:/router?id=123&userName=why
方法一:动态路由params


父
<template><router-link to="/user/zhangsan"></router-link><!--to要用v-bind绑定属性,相当于路径是/user/abc--><router-link :to="'/user/'+user"></router-link><router-view></router-view></template><script>export default {name:'name',data(){return {//绑定router-link标签的to属性,添加一个变量,实现动态路由user:'abc'}}}</script>
子通过页面路由属性对象route的属性params 获取到{ id : abc }
route获取和使用可以查看 Vue Router - 页面路由属性 route
方法二:query类型

父组件
通过to里面的参数query,把对象传入子组件
<router-link :to="{path:'/hi',query:{name:'abc',age:18}}">kk</router-link><!--点击后,浏览器变为:locahost:80/hi?name=abc&age=18-->
父组件还可以通过父组件的变量,把值传入
<template><div><router-link :to="{path:'/about/test2',query:{name:myName,age:31}}">Test2</router-link><router-view /></div></template><script>export default {data() {return {myName:"yjl"};}};</script>
子组件
子通过页面路由属性对象route的属性query获取到 {name:’abc’,age:18}
<template><div>{{ $route.query.name}}{{ $route.query.age}}</div></template>
获取和使用可以查看 Vue Router - 页面路由属性 route
====================
导航守卫
vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
也就是根据跳转时拦截跳转,然后判断条件,来决定跳转还是取消跳转。
比如跳转时如果是登录页面,就清除cookie;如果跳转的页面没有对应的权限,就跳回主页等等。
完整导航触发

类似于导航的生命周期函数,基本的就是导航跳转前执行、跳转的组件加载完成后执行、跳转完成后执行。
一般用的多的就是beforeEach,其他用的少
全局守卫
全局的意思是,只要发生跳转行为,不管发生多少次,每次都会统一触发。
如跳转后修改网页的title;用于显示主页前验证是否登录,没登录就跳转到登录界面等。
全局守卫,要写在在router里面的index.js文件内。
const router = new VueRouter({mode: 'history',linkActiveClass:"active",routes})//导航跳转前执行函数router.beforeEach((to,from,next)=>{console.log("beforeEach");//一定要调用next()方法,否则浏览器不会自动完成跳转next();});//跳转的组件加载完成后执行函数(所有组件内守卫和异步路由组件被解析之后)router.beforeResolve((to,from,next)=>{console.log("beforeResolve");//一定要调用next()方法,否则浏览器不会自动完成跳转next();})//跳转完成后执行函数,不会接受 next 函数也不会改变导航本身router.afterEach((to,from)=>{console.log("afterEach");})export default router
每个守卫方法参数(to,from,next)

默认导航:正常跳转,该去哪还是去哪;
路径地址:直接跳转这个路径地址,可以是路径字符串或者对象,类似于{ path : ‘ /user ‘ , query : { a:1 } }
next

组件内守卫
就是组件内,只要发生跳转,就会触发执行3种函数。
都需要调用next( ) 方法,否则跳转不了。
<template><div>123</div></template><script>export default {data() {return {};},beforeRouteEnter:function(to, from, next){// 跳转到这个组件前,执行函数// 不!能!获取组件实例 `this`,因为当守卫执行前,组件实例还没被创建console.log("组件beforeRouteEnter");next();},beforeRouteUpdate (to, from, next) {// 在当前路由改变,但是该组件被复用时调用// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。// 可以访问组件实例 `this`console.log("组件beforeRouteUpdate");next();},beforeRouteLeave (to, from, next) {// 导航离开该组件的对应路由时调用// 通常用来禁止用户在还未保存修改前突然离开// 可以访问组件实例 `this`console.log("组件beforeRouteLeave");next();}};</script>
路由独享守卫
const router = new VueRouter({routes: [{path: '/foo',component: Foo,beforeEnter: (to, from, next) => {// ...}}]})
meta 元数据
router里面的index.js文件内,可以给每个页面添加元数据,后面路由时,可以调用to.matched[0].meta 或 from.matched[0].meta 方法来获取相应组件的元数据
{path: '/Hello',name: 'Hello',//meta是元数据,描述数据的数据meta:{title:'abc'}
keep-alive 缓存页面
vue2


vue 3
包含 include
排除name=Profile的组件,其他组件保留缓存,可以被缓存
排除 exclude
排除name=Profile的组件,其他组件保留缓存,这个组件频繁创建和销毁。
多个组件可以用逗号隔开,但不能加空格
激活、失去激活

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