当前位置: 首页 > news >正文

【vue-router】动态路由、嵌套路由、守卫以及编程式导航

目录

一、编程式导航

⭕️实现页面跳转的方式

⭕️参数传递的方式

例子

二、嵌套路由

三、动态路由匹配

四、导航守卫 

1、全局守卫

全局前置守卫

全局后置守卫

2、路由独享守卫

3、组件内守卫

五、监听路由url地址栏变化的方法

六、路由模式 


一、编程式导航

编程式导航是用来做页面跳转的。

使用 <router-link> 创建 a 标签来定义导航链接实现路由跳转的方式叫做声明式导航

编程式导航是指借助 router 的实例方法,通过编写代码来实现。

⭕️实现页面跳转的方式

1、$router.push

使用$router.push()跳转到指定路由,会向history栈添加一个新的记录,当用户点击浏览器回退按钮的时候,可以回到跳转前的url。

this.$router.push({
  path:'/aDetails',
  query:{id}
})

2、$router.replace

使用$router.replace不会往浏览器添加历史记录

this.$router.replace({
  path:"/aDetails",
  query:{id}
})

3、$router.go

$router.go用来跳转到指定页面,前进或后退都可以

//前进一步记录
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 不传递参数或者参数为 0,表示刷新当前页面
router.go()
// 如果 history 记录不够用,则会报错
router.go(-100)
router.go(100)

4、使用<router-link>标签(本质上是a标签)

5、使用a标签

⭕️参数传递的方式

1、path-query传参

this.$router.push({
  path:'/aDetails',
  query:{id}
})

使用path与query结合的方式传递参数时,参数会被拼接在浏览器地址栏中,并且刷新页面后数据也不会丢失。  

2、name-params传参

this.$router.push({
  name:"ADetails",
  params:{id},
})

使用name与params结合的方式传递的参数时,参数是携带在$route中的,且传递的参数是一次性的,刷新页面数据会丢失。 

例子

写个小案例:
点击文章标题跳转文章详情页(在vue-cli中写)

在components下创建两个组件:Article.vue和ArticleDetails.vue

在router下的index.js配置路由:
 

  App.vue

  

Article.vue

ArticleDetails.vue 

 this.$route打印的结果:

 运行结果如下: 

可以看出,使用query传参,参数是携带在地址栏上的。 

二、嵌套路由

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件。

例子:

在components下创建三个组件:AboutOne.vue、AboutTwo.vue、AboutThree.vue

 AboutOne.vue

<template>
  <div>
    about-one
  </div>
</template>

AboutTwo.vue

<template>
  <div>
    about-two
  </div>
</template>

AboutThree.vue

<template>
  <div>
    about-three
  </div>
</template>

在router下的index.js 配置路由:

 views下的AboutView.vue

<template>
  <div class="about">
    <div><router-link to='aboutone'>about1</router-link></div>
    <div><router-link to='abouttwo'>about2</router-link></div>
    <div><router-link to='aboutthree'>about3</router-link></div>
    <div>
      <router-view></router-view>
    </div>  
  </div>
</template>

 

三、动态路由匹配

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。

例如 : 有一个user组件,对于所有id不同的用户,都要使用这个组件来渲染,那么可以在vue-router的路由路径中使用动态路径参数来达到这个效果。动态路径参数使用冒号进行标识。

index.js 

App.vue 

 

可以看到,当我们更改动态路径参数时,页面没有发生跳转,仍然是当前页面。

四、导航守卫 

当路由发生改变的时候会触发导航守卫。导航守卫分为全局守卫、路由独享守卫和组件内守卫。

1、全局守卫

全局前置守卫

beforeEach((to,from,next)=>{
  next();//手动调用向下执行
  next(fale);//阻止路由向下执行				
})

参数说明:

to:即将要进入的目标路有对象
from:当前导航正要离开的路由
next:是一个函数,一定要调用该方法来执行这个钩子。执行效果依赖 next 方法的调用参数,参数默认为true,表示向下执行,false表示阻止路由向下执行。

全局后置守卫

全局后置守卫没有next方法,它不需要调用next方法让路由向下执行

afterEach((to,from)=>{

})

2、路由独享守卫

路由独享守卫需要进入到当前路由才会触发。

beforeEnter((to,from,next)=>{

})

3、组件内守卫

//进入组件路由时触发
beforeRouteEnter(to,from,next){};
//组件路由更新时触发
beforeRouteUpdate(to,from,next){};
//离开组件路由时触发
beforeRouteLeave(to,from,next){};

beforeRouteEnter中的this指向window,

beforeRouteUpdate 和 beforeRouteLeave中的this指向组件实例。

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.5.4/vue-router.min.js"
		integrity="sha512-zxWuRslhjyZyRAYInXTNl4vC/vBBwLQuodFnPmvYAEvlv9XCCfi1R3KqBCsT6f9rk56OetG/7KS9dOfINL1KCQ=="
		crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>

<body>
	<div id="app">
		<!-- 使用路由 to表示要去的路由-->
		<router-link to="/article">去文章管理</router-link>
		<router-link to="/column">去栏目管理</router-link>
		<router-link to="/user/1">用户管理</router-link>
		<!-- 路由出口 匹配路由对应的组件 -->
		<router-view></router-view>
	</div>
	<script>
    // 组件article
		let article = {
			template: `
				<div>文章页面</div>
			`,
		};
    // 组件user 
		let user = {
            template: `
				<div>用户页面---{{id}}</div>
			`,
			// 4、组件内守卫
			beforeRouteEnter(to, from, next) {
				console.log(this, 'beforeRouteEnter');
				console.log(to, from);
				next()
			},
			beforeRouteUpdate(to, from, next) {
				console.log(this, 'beforeRouteUpdate');
			},
			beforeRouteLeave(to, from, next) {
				console.log(this, 'beforeRouteLeave');
				next()
			},
			data() {
				return {
					id: 0
				}
			},
		};
    // 组件column
		let column = {
			template: `
				<div>栏目页面</div>
			`
		};
		// 配置路由对象数组
		let routes = [
			{
				path: '/article',
				component: article
			},
			{
				path: '/column',
				component: column,
				// 3、路由独享守卫 只有进入当前路由时才会触发
				beforeEnter: (to, from, next) => {
					console.log(to,from,next);
					next();
				}
			},
			{
				path: '/user/:id',
				component: user
			}
		];
		// 创建路由器对象router
		let router = new VueRouter({
			routes,
		});
		
    // 1、全局前置守卫
		router.beforeEach((to,from,next)=>{
			console.log(to,from,next);
			next()
		  // next(false);//阻断路由向下执行
		});
		// 2、全局后置守卫 
		router.afterEach((to,from)=>{
			console.log(to,from);
		})
		new Vue({
			router,
			el: "#app",
			data: {

			}
		})
	</script>
</body>

</html>

五、监听路由url地址栏变化的方法

1、在created中监听

created(){
  console.log(this.$route.params.xxx)
}

2、使用watch监听

watch:{
  $route(to,from){
    //to ---即将进入的路由
    //from --上一个离开的路由
    console.log(to.params)
  }
}

3、使用组件内守卫监听 (组件更新时会触发的钩子)

beforeRouteUpdate(to,from,next){
  console.log(to.params)
  next()
}

通过监听地址栏变化,可以获取到携带在地址栏上的参数。 

六、路由模式 

路由模式有hash模式和history模式,默认是hash模式。

路由模式在路由器对象中设置:

let router = new VueRouter({
    routes,
	// 路由模式
	mode: 'history'
	// mode: 'hash'
});

hash模式的工作原理是hashchange事件,可以在window监听hash的变化。我们在url后面随便添加一个#xx触发这个事件。

window.onhashchange = function (event) {
	console.log(event);
}

打印出一个HashChangeEvent事件对象,在该对象内有newURL和oldURL  

把window.history对象打印出来,history对象内有back()、forword()、go()等方法:

两者的区别:
1、hash会在路由路径中携带#,history在路由路径不会携带#
2、hash刷新页面不会请求服务器,history刷新页面会请求服务器
3、hash工作原理是hashchange事件
4、history工作原理是利用go、back、forward
5、hash支持低版本的浏览器,history是h5新增api

相关文章:

  • 工程师们不断推动下的云服务架构
  • Vue3中的watch监听
  • 【国产数据库】数据迁移至openGauss
  • 一道晦涩难懂的Pandas基础题
  • 边缘计算:一文理解云边端协同架构中的高性能云计算、边缘计算、云边协同
  • 【算法刷题篇】——算法入门 01 数据结构——栈(一)
  • 使用python进行数据分析(二)
  • C++实现二分法求零点(二分法求零点)
  • SECS/GEM半导体协议介绍
  • ARM接口实验-LED灯实验(A7核)
  • 经典卷积和深度卷积的神经网络
  • 【C语言】一篇文章彻底搞懂变量和常量
  • CSS基础12-canvas
  • javascript时钟的开发制作
  • 应用层协议 —— HTTP(二)
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • co模块的前端实现
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • es的写入过程
  • Magento 1.x 中文订单打印乱码
  • Nodejs和JavaWeb协助开发
  • Python语法速览与机器学习开发环境搭建
  • sublime配置文件
  • 高性能JavaScript阅读简记(三)
  • 用element的upload组件实现多图片上传和压缩
  • 再谈express与koa的对比
  • linux 淘宝开源监控工具tsar
  • 移动端高清、多屏适配方案
  • #{}和${}的区别是什么 -- java面试
  • #传输# #传输数据判断#
  • (11)MSP430F5529 定时器B
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (ZT)薛涌:谈贫说富
  • (二)pulsar安装在独立的docker中,python测试
  • (接口封装)
  • (十六)串口UART
  • (转载)Linux 多线程条件变量同步
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .net6使用Sejil可视化日志
  • .NET序列化 serializable,反序列化
  • @JsonFormat与@DateTimeFormat注解的使用
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • @RequestMapping 的作用是什么?
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]
  • [2016.7 test.5] T1
  • [383] 赎金信 js
  • [Android Studio 权威教程]断点调试和高级调试
  • [AutoSar]BSW_OS 01 priority ceiling protocol(PCP)
  • [C++]二叉搜索树
  • [CareerCup] 13.1 Print Last K Lines 打印最后K行
  • [CSS]CSS 的背景