前言
Vue Router 是Vue 框架的一个非常重要的功能。
目标
1 单页应用程序和多页应用程序之间的区别。
2 vue-router的具体实现方法;
3 什么是路由模式以及它们有何不同?
4. 如何实现根防护和根缓存。
一 路由的概念
概念
Vue Router 是Vue 提供的路由管理器。组件和路由之间存在一一对应的关系,这种对应关系称为路由。
Vue是一个典型的SPA单页面应用框架。 SPA单页是指你的网站只有一个HTML页面,所有的页面切换都是在这一页面上完成的。所有不同组件之间的切换都是通过单页和多页应用程序完成的。
当编程开发兴起时,使用多个HTML页面来进行页面之间的切换。这是第一个MPA 多页应用程序。随着技术的发展,这种页面切换方式的缺点也逐渐显现出来。例如,每次切换页面时都需要加载资源,这会导致用户体验非常差,并且会给服务器带来很大的负载。为了解决多页面应用的问题,引入了SPA单页面应用。 SPA单页面应用是指单个HTML页面,通过路由实现不同组件之间的切换。当您第一次进入页面时,会加载相关资源并将内容功能封装到组件中。页面切换的底层是组件切换,它解决了多页面应用的很多缺点。然而,单页应用程序并不完美。首次加载相关资源时,SPA首页加载缓慢。
分类实现方法、页面性能、开发效率、用户体验、首屏加载、其他页面加载、SEO、单页、一个HTML、按需更新性能、高、很好、慢、快、差、多页、多html,页面整体更新性能,差,一般,平均,速度,慢,优秀
SPA单页面和MPA多页面应用方式各有优缺点,根据您项目的需求,可以选择更合适的开发方式(SPA应用是目前的主流)。
vue-router 是Vue.js 的官方路由插件,与vue.js 紧密集成,适合构建单页应用程序。
二 准备工作
1 安装
npm 安装vue-router@3.6.5 –save
这里需要注意的是,Vue版本必须与vue-router版本相对应。否则在安装过程中将无法使用。
vue2.x对应的vue-router版本是vue-router3.x。
vue3.x对应的vue-router版本是vue-router4.x2。
从‘vue-router’导入路由器//导入
Vue.use(Router) //注册
new Router({})//创建路由
一个项目不能只有一两个路由和组件映射。
如果你的路由很多,直接在main.js中写路由配置显然更难维护。我们将直接创建一个封装router.js 的文件。
登录后复制
从“vue”导入Vue
从“vue-router”导入路由器
//引入组件
从“./views/HelloWord”导入helloWord
从“./views/School”导入学校
Vue.use(路由器)
//路由和组件绑定
导出默认的新路由器({
根: [ {
name:\’学校\’,
路径: \’/学校\’,
组件: 学校
},{
name:\’地狱之言\’,
path: \’/helloWord\’,
组件: helloWord,
}]
})
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19。
3 全球导入路由
在main.js 中全局导入
登录后复制
从“./router”导入路由器
新Vue({
el: \’#app\’,
router, //引入路由
render: h=h(应用程序),
创建之前(){
//全局事件总线
Vue.prototype.$bus=this
}
}).$mount(\’#app\’)
1.2.3.4.5.6.7.8.9.10。
现在准备工作已经完成。
如果你对上面的操作满意,你可以将vur-router提供的$router和$route方法打印到控制台。打印成功后,就可以使用路由了。
r
啊
你
t
e
每个组件的唯一路由信息
Routes 每个组件自己的路由信息
每个组件唯一的路由信息路由器全局相同,是通用的路由方法。
三 路由基本方法
3.1 声明式导航与编程式导航
声明式路由导航
声明式导航使用模板中的特定指令来实现页面导航。在Vue模板中,使用router-link组件创建导航链接,并设置to属性来指定目标路由或命名路由的路径。例如:
登录后复制
router-link to=\’/search\’ 跳转到搜索页面/router-link
1.
优点:简单直观,在模板中编写导航链接不需要额外的Js代码。程序化导航
程序化导航是通过使用Vue Router提供的JS代码中的API实现页面导航来实现的。一旦你访问了$router对象,你就可以使用它提供的方法(push、replace、go等)来跳转到页面。例如:
登录后复制
this.$router.push(\’/search\’);
1.
优点:可以根据条件或者Js代码中的动态数据进行导航,更加灵活可控。
1 声明式导航
路由器链接
通过设置to 属性指定路径(必需)。本质还是标签,所以没必要#。
to 后面可以跟路径或名称
登录后复制
//到路径。默认类似于$router.push,跳转到路由并添加路由历史记录。
router-link class=\’link\’ to=\’/helloWord\’Helloword/router-link
//姓名
router-link class=\’link\’ to=\’helloword\’Helloword/router-link
//替换当前历史记录并跳转到指定路由
router-link class=\’link\’ 替换为=\’helloword\’Helloword/router-link
1.2.3.4.5.6。
2 编程式导航
$router.push
跳转到指定路由,并在路由信息中添加历史信息
登录后复制
按钮类=\’链接\’@click=\’jump(1)\’hellword/button
跳转(类型){
console.log(\’类型\’, 类型)
如果(类型==1){
//路径方法跳转
//this.$router.push(\’/helloWord\’)
//this.$router.push({path:\’/helloWord\’})
//命名方法跳转
this.$router.push({name:\’地狱之言\’})
} 除此之外{
this.$router.push(\’/school\’)
}
}
1.2.3.4.5.6.7.8.9.10.11.12.13。
$router.replace
替换当前历史记录并跳转到指定路线
登录后复制
按钮类=\’链接\’@click=\’jump(1)\’hellword/button
跳跃(类型){
console.log(\’类型\’, 类型)
如果(类型==1){
this.$router.replace({name:\’地狱之言\’})
} 除此之外{
this.$router.push(\’/school\’)
}
}
1.2.3.4.5.6.7.8.9。
$router.go()
您可以在浏览历史记录中向前或向后移动(正数- 向前,0 – 刷新,负数- 向后)
登录后复制
this.$router.go(0) //更新
this.$router.go(-1) //返回1
1.2.
$router.back()
返回历史记录的上一页$router.forward()
转到历史记录的下一页
完整代码
登录后复制
模板
div id=\’应用程序\’
小时/时间
div 类=\’flex\’
div 类=\’Navi\’
方法一
router-link class=\’link\’ to=\’/helloWord\’Helloword/router-link
router-link class=\’link\’ to=\’/school\’school/router-link
方法2
按钮类=\’链接\’@click=\’jump(1)\’hellword/button
按钮类=\’链接\’@click=\’jump(2)\’学校/按钮
/div
div 类=\’内容\’
路由器视图/路由器视图
/div
/div
/div
/模板
脚本
导出默认值{
name: \’应用程序\’,
数据() {
返回{
};
},
安装(){
},
方法:{
跳跃(类型){
console.log(\’类型\’, 类型)
如果(类型==1){
//路径方法跳转
//this.$router.push(\’/helloWord\’)
//this.$router.push({path:\’/helloWord\’})
//命名方法跳转
//this.$router.push({name:\’hellword\’})
} 除此之外{
this.$router.push(\’/school\’)
}
},
},
};
/剧本
风格
应用程序{
font-family: Avenir、Helvetica、Arial、无衬线字体;
-webkit-font-smoothing: 抗锯齿;
-moz-osx-font-smoothing: 灰度;
文本对齐:居中;
color: #2c3e50;
边距-top: 60px;
}。柔性{
显示器: Flex。
}
.nav {
宽度: 120 像素;
显示器: Flex。
flex-direction: 列;
}。关联{
边距: 3px 10px;
宽度: 100 像素;
高度: 60 像素;
行高: 60px;
字体大小: 20px;
文本装饰: 无。
border: 1px 纯蓝色;
边框半径: 4px;
}。内容{
width: 计算(100% – 100px);
高度: 800 像素;
背景颜色: #eee;
}
/风格
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.4 4.45.46.47.48.49.50 51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.75.76.77.78.79.80.81.82。
执行结果
3.2 嵌套(多级)路由
学校部分下还有学生路线。这可以写成:
/子页面访问路径/school/student没有添加到子子根路径中。
登录后复制
导出默认新路由器({
根: [ {
name:\’学校\’,
路径: \’/学校\’,
组成部分:学校,
孩子:[{
name:\’学生\’,
path: \’学生\’,
组件:学生,
}]
},{
name:\’你好词\’,
path: \’/helloWord\’,
组件: helloWord,
}]
})
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16。
学校组成部分
登录后复制
模板
分配
我在学校
时间
div @click=\’$router.push(\’/school/student\’)\’显示学生/div
路由器视图/路由器视图
/div
/模板
1.2.3.4.5.6.7.8。
3.3 路由中的参数
3.3.1 query参数
显式传递参数1. 在路径后加入参数2. 通过编程路由传递查询参数
登录后复制
this.$router.push({path:\’/helloWord\’,query:{id:\’01\’,name:\’张二\’}})
1.
3 注册路由参数
注册路由时一般不需要添加参数。
登录后复制
{
name:\’你好词\’,
path: \’/helloWord\’,
组件: helloWord,
查询:{
id:\’02\’,
name:\’张三\’
}
}
1.2.3.4.5.6.7.8.9。
3.3.2 params参数
1 pass后传递参数
登录后复制
path: \’/helloWord/:id/:name\’ //比较ID和名称的位置
1.
2 编程式路由参数传输
登录后复制
this.$router.push({name:\’helloword\’,params:{id:\’01\’,name:\’张二\’}})
1.
: 特别注意,如果路由携带参数作为参考,则参数不能与路径一起使用,只能与名称一起使用。
params 方法仅通过上面列出的两种方式传递参数。
3.4 命名路由
然后,您可以使用名称而不是路径将to 属性传递给路由器链接。
登录后复制
导出默认新路由器({
根: [ {
name:\’学校\’,
路径: \’/学校\’,
组成部分:学校,
孩子:[{
name:\’学生\’,
path: \’学生\’,
组件:学生,
}]
}]
})
1.2.3.4.5.6.7.8.9.10.11.12。
3.5 props
根props参数1是一个对象,该对象中的所有键值都会以props的形式传递给组件。
登录后复制
{
name:\’你好词\’,
path: \’/helloWord\’,
组件: helloWord,
props:{id:\’003\’,name:\’林三毛\’},
}
1.2.3.4.5.6。
登录后复制
模板
分配
我是你好词
/div
/模板
脚本
导出默认值{
name: \’HelloWord\’,
props:[\’id\’,\’name\’], //接收参数
安装(){
console.log(\’======id======\’,this.id)
console.log(\’======名称======\’,this.name)
}
}
/剧本
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15。
2 布尔值。如果值为true,则路由组件接收到的所有params 参数都会以props 的形式传递给组件。
登录后复制
{
name:\’你好词\’,
path: \’/helloWord\’,
组件: helloWord,
道具:true
}
1.2.3.4.5.6。
登录后复制
this.$router.push({name:\’helloword\’,params:{id:\’01\’,name:\’张二\’}})
模板
分配
我是你好词
/div
/模板
剧本&
gt;
export default {
name: \’HelloWord\’,
props:[\’id\’,\’name\’], // 接收传参
mounted(){
console.log(\’=====id======\’,this.id)
console.log(\’=====name======\’,this.name)
}
}
</script>
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.
3 值为函数
登录后复制
{
name:\’helloword\’,
path: \’/helloWord\’,
component: helloWord,
props($route){
// $route组件的路由信息
return {id:$route.query.id,name:$route.query.name}
},
query:{
id:\’02\’,
name:\’张三\’
}
}
1.2.3.4.5.6.7.8.9.10.11.12.13.
登录后复制
<template>
<div>
我是HelloWord
</div>
</template>
<script>
export default {
name: \’HelloWord\’,
props:[\’id\’,\’name\’], // 接收传参
mounted(){
console.log(\’=====id======\’,this.id)
console.log(\’=====name======\’,this.name)
}
}
</script>
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.
四 路由守卫
执行顺序
跳转
前置路由守卫
独享路由守卫
组件内路由守 – 进
组件内路由守卫 – 离
后置路由守卫
4.1 全局路由守卫(前/后置)
routes路由中的属性不可以随意的自定义,而是要在meta属性中自定义,其他地方自定义属性都会失效
登录后复制
Vue.use(Router)
const routes = new Router({
routes: [ {
name:\’school\’,
path: \’/school\’,
component: School,
meta:{
isAuth:true,
title:\’学校\’
},
children:[{
name:\’student\’,
path: \’student\’,
component: Student,
meta:{
isAuth:true,
title:\’学生\’
},
}]
},
{
name:\’helloword\’,
path: \’/helloWord\’,
component: helloWord,
meta:{
isAuth:true,
title:\’首页\’
},
}]
})“`
**前置路由守卫 beforeEach**,顾名思义在路由跳转之前执行,这里一般可以做页面权限校验等操作
“`c
// 前置路由守卫
/**
to 目的地
from 起始地
next 放行
**/
routes.beforeEach((to,from,next)=>{
if(to.meta.isAuth){
next()
}
})
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.
前置路由守卫 beforeEach,顾名思义在路由跳转之前执行,这里一般可以做页面权限校验等操作。
初始化时候、每次路由切换之前被调用
登录后复制
// 前置路由守卫
/**
to 目的地
from 起始地
next 放行:路由跳转,next下的代码还会继续的执行
**/
routes.beforeEach((to,from,next)=>{
if(to.meta.isAuth){
next()
}else{
alert(\’你没有权限\’)
}
})
1.2.3.4.5.6.7.8.9.10.11.12.13.
后置路由守卫 afterEach,顾名思义在路由跳转之后执行,这里可以做title更改。
初始化时候、每次路由切换之后被调用
登录后复制
// 后置路由守卫
/**
to 目的地
from 起始地
**/
routes.afterEach((to,form)=>{
document.title = to.meta.title
})
1.2.3.4.5.6.7.8.
4.2 独享路由守卫
独享路由守卫 beforEnter,顾名思义就是某一个路由独自享有的,只由触发改路由时才会执行类似路由的前置
执行顺序:全局前置 –> 独享路由 –> 全局后置
登录后复制
children:[{
name:\’student\’,
path: \’student\’,
component: Student,
meta:{
isAuth:true,
title:\’学生\’
},
// to form 用法同上
beforeEnter:(to,form,next)=>{
console.log(to,form);
next()
}
}]
1.2.3.4.5.6.7.8.9.10.11.12.13.14.
4.3 组件内路由守卫
在组件内部设置该组件的路由守卫beforeRouteEnter 进入该组件时触发beforeRouteLeave 离开该组件时触发(切换路由)
登录后复制
<template>
<div>
我是HelloWord
</div>
</template>
<script>
export default {
name: \’HelloWord\’,
props:[\’id\’,\’name\’],
data(){
return{}
},
// 进入该该组件时触发
beforeRouteEnter(to,from,next){
console.log(\’=====enter-to======\’,to)
console.log(\’=====enter-from======\’,from)
next()
},
// 离开该组件时触发
beforeRouteLeave(to,from,next){
console.log(\’=====leave-to======\’,to)
console.log(\’=====leave-from======\’,from)
next()
}
}
</script>
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.
五 其它
5.1 路由模式
1. hash模式
修改为hash模式
登录后复制
const routes = new Router({
// 模式 默认为hash
mode: \’hash\’,
})
1.2.3.4.
#及其后面的值都是hash值
将打包后的文件发布到服务器上(如何没有线上服务器可以启动本地服务发布参考:)
hash值有特殊的#标识,不会传送给服务器端
2. history模式
修改为history模式
登录后复制
const routes = new Router({
// 模式
mode: \’history\’,
})
1.2.3.4.
打包后发到本地无服务上,点击可以正常的访问,但是一旦刷新页面就如下所示,这是因为刷新的时候页面会当成资源去请求服务器,服务器找不到此接口就会报错
解决办法:
node中connect-history-api-fallback插件是专门解决此问题的;ngix中配置分辨是否前端路由通过后端去处理
3. 总结
hash模式
1.地址中永远带着#号,不美观。
2.若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
3.兼容性较好。
4.hash值不会包含在 HTTP 请求中,即: hash值不会带给服务器。
history模式
1.地址干净,美观。
2.兼容性和hash模式相比略差。
3.应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。
5.2 keep-alive缓存路由组件
原理
我们知道vue是通过vnode实现保存节点的,而keep-alive本身也是通过保存vnode来实现缓存的,而不是直接存储DOM结构。其实就是将需要缓存的VNode节点保存在this.cache中,在render时,如果VNode的name符合在缓存条件(可以用include以及exclude控制),则会从this.cache中取出之前缓存的VNode实例进行渲染。
作用
keep-alive组件是vue2.0提供的一个缓存组件,在组件切换过程中把切换出去的组件保留在内存,不被销毁,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性
效果
keep-alive组件,只要将子组件嵌套在这里面就可以实现组件的缓存,当页面返回时数据不会丢失,实现了我们常见的历史页面不刷新的效果
参数Props
include – 类型字符串、数组以及正则表达式,只有匹配的组件会被缓存exclude – 类型字符串、数组以及正则表达式,匹配的组件不会被缓存max – 类型字符或者数字,可以控制缓存组件的个数,缓存组件的最大值
登录后复制
// 只缓存组件name为a或者b的组件
<keep-alive include=\”a,b\”>
<component />
</keep-alive>
// 组件name为c的组件不缓存(可以保留它的状态或避免重新渲染)
<keep-alive exclude=\”c\”>
<component />
</keep-alive>
// 如果同时使用include,exclude,那么exclude优先于include, 下面的例子只缓存a组件
<keep-alive include=\”a,b\” exclude=\”b\”>
<component />
</keep-alive>
// 如果缓存的组件超过了max设定的值5,那么将删除第一个缓存的组件
<keep-alive exclude=\”c\” max=\”5\”>
<component />
</keep-alive>
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.
用法
1、与include结合使用
登录后复制
// include 只缓存组件名字为home的组件,其他组件不会缓存,而exclude恰好相反
<keep-alive include=\”home\”>
<router-view />
</keep-alive>
1.2.3.4.
2、结合Router中的meta属性来控制组件缓存
登录后复制
{
path: \’/\’,
name: \’home\’,
meta:{
keepAlive:true // 需要缓存
},
component: Home,
children: [
{
path: \’goods\’,
name: \’goods\’,
component: Goods,
meta: {
keepAlive: false // 不需要缓存
}
}
]
}
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.
登录后复制
<keep-alive>
<router-view v-if=\”$route.meta.keepAlive\” />
</keep-alive>
<router-view v-if=\”!$route.meta.keepAlive\” />
1.2.3.4.
缓存所有页面:
登录后复制
在app.vue页面里加keep-alive
缓存部分页面:
登录后复制
1、在app.vue页面里加keep-alive,结合keep-alive的include属性
2、结合Router中的meta属性,在app.vue页面里加$route.meta.keepAlive的if判断
小知识点
1、同时使用include,exclude,那么exclude优先于include
2、缓存的组件超过了max设定的值5,那么将删除第一个缓存的组件
3、keep-alive 不会在函数式组件中正常工作,因为它们没有缓存实例
4、keep-alive 先匹配被包含组件的 name 字段,如果 name 不可用,则匹配当前组件 components 配置中的注册名称
5、只有组件被 keep-alive 包裹时,这两个生命周期函数才会被调用,如果作为正常组件使用,是不会被调用的,以及在 2.1.0
版本之后,包含在 keep-alive 中,但符合 exclude ,不会调用activated和
deactivated这两个函数钩子!另外,在服务端渲染时,此钩子函数也不会被调用
5.3 生命周期变化
针对路由缓存组件的多加了两个生命周期函数
1.activated
在 keep-alive 组件激活时调用该钩子函数在服务器端渲染期间不被调用使用 keep-alive会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在 activated 阶段获取数据,承担原来 created钩子函数中获取数据的任务。
登录后复制
activated(){
/**
* 缓存的组件点击时调用
*/
},
1.2.3.4.5.
2.deactivated
在 keep-alive 组件停用时调用该钩子函数在服务器端渲染期间不被调用被包含在 keep-alive中创建的组件,会多出两个生命周期的钩子: activated 与 deactivated
登录后复制
deactivated(){
/**
* 缓存的组件点击时调用
*/
},
1.2.3.4.5.
keep-alive的用法及详解
总结
1、如何配置路由?
2、如何使用导航进行路由跳转
声明式:router-link
编程式:this.$ router.push,this.$ router.g等
3、嵌套(多级)路由如何配置与使用
父级路由中加children,children下就是子路由子路由中的path不加/子页面访问路径 /school/student
4、路由如何传递传参
this.$router.push({path:‘/helloWord’,query:{id:‘01’,name:‘张二’}})
this.$router.push({name:‘helloword’,params:{id:‘01’,name:‘张二’}})
props
路径冒号参数项:about/:id/:name
5、路由守卫
前置守卫 routes.beforeEach((to,from,next)=>{}) ,后置守卫 routes.afterEach((to,from,next)=>{})
独享路由守卫
组件内路由守卫
6、路由缓存
keep-alive
#以上关于【Vue】vue的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/93272.html