路由介绍
映射表:路由器的功能就是储存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 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。