vue第三堂课

开启路由新篇章

前段路由介绍

vue+vue-router 主要是来做单页面应用(Single Page Application)

为什么要做单页面应用:

  • 传统的开发方式url改变后立马发送请求到后端,响应整个页面,有可能资源过多,传统开发会让前端整个页面出现“白屏”,用户体验不好
  • SPA(单页面应用):锚点值的改变后,不会立刻发送请求,而是在某个合适的时机,发送ajax请求,局部改变页面中的数据,页面不立刻跳转,用户体验好。

前段路由原理

  1. 锚点值(锚点值就是a标签的href属性) 监视
  2. ajax获取动态的数据
  3. 核心点是锚点值的改变

访问#/login的时候让其进入登录页面,访问#/register时进入注册页面。
onhashchange事件,是url上的锚点数据改变就会触发这个事件,锚点数据就是:#/xxx。页面是不跳转的,只在当前页面渲染,是局部的数据刷新。
代码1

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
		*{
			padding: 0,
			margin:0;
		}
	</style>
</head>
<body>

<a href="#/login">登录</a>
<a href="#/register">注册</a>
<div id='app'>
</div>

<script type="text/javascript">
	// 监视锚点值发生变化,触发事件,
	window.onhashchange = function(){
		console.log(location.hash);
	}
</script>
</body>
</html>

在这里插入图片描述
代码2

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin:0;
		}
		#app{
			width: 300px;
			height: 400px;
			background-color: yellow;
		}
	</style>
</head>
<body>

<a href="#/login">登录</a>
<a href="#/register">注册</a>
<div id='app'>
</div>

<script type="text/javascript">
	// 监视锚点值发生变化,触发事件
	var oDiv = document.getElementById('app');
	window.onhashchange = function(){
		console.log(location.hash);
		// 根据不同的锚点值,对页面进行切换
		switch (location.hash){
			case '#/login':
				oDiv.innerHTML = '<h2>登录页面</h2>';
				break;
			case '#/register':
				oDiv.innerHTML = '<h2>注册页面</h2>';
				break;
			default:
				break;
		}
	}
</script>
</body>
</html>

在这里插入图片描述

vue-router的基本使用

是vue中的核心插件,下载:

  1. 在项目根目录npm init --yes
  2. npm install vue-router --save

使用:
1.引入 vue-router的对象<script type="text/javascript" src="./node_modules/vue-router/dist/
2.让vue使用该VueRouter创建Vue.use(VueRouter)
3.创建一个路由对象,路由对象中使用的组件一定要在创建路由对象之前声明。
4.router对象挂载到vue实例化对象中。

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin:0;
		}
	</style>
</head>
<body>
<div id='app'>
</div>

<script type="text/javascript" src="./vue.js"></script>
<!-- 1.引入 vue-router的对象 -->
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
<!-- vue-router.js返回的是全局的VueRouter对象。 还提供了两个全局组件 router-link router-view.-->

<script type="text/javascript">
	// 2.让vue使用该VueRouter创建
	Vue.use(VueRouter)
	

	var Login = {
		template:`
			<div>登录组件</div>
		`
	}
	var Register = {
		template:`
			<div>注册组件</div>
		`
	}

	// 3.创建一个路由对象
	var router = new VueRouter({
		// 配置路由对象
		// 数组中存放各个路由
		routes:[
			{
				// 访问path路由时,加载一个Login组件
				path: '/login',
				component:Login
			},
			{
				path: '/register',
				component:Register
			}
		]
	})

	var App = {
		template:`
			<div>
				<!-- router-link默认会被渲染成a标签, to属性默认会被渲染成href属性。 -->
				<router-link to="/login">登录</router-link>
				<router-link to="/register">注册</router-link>

				<!-- router-view, 路由组件的出口 -->
				<router-view></router-view>
			</div>
		`,
	}

	new Vue({
		el:'#app',
		template:`<App />`,
		components:{
			App
		},
		// 4.挂载router对象,key,value一样可以缩写,router:router等价于router
		router:router,
	})
</script>
</body>
</html>

流程分析:
在这里插入图片描述
在这里插入图片描述
点击登录
在这里插入图片描述

命名路由

给路由起个名字。
1.给当前的配置路由信息对象设置name: 'login'属性
2.:to="name:'login'"

	var router = new VueRouter({
		// 配置路由对象
		// 数组中存放各个路由
		routes:[
			{
				// 访问path路由时,加载一个Login组件
				path: '/login',
				name: 'login',  // 1. 给路由起名字
				component:Login
			},
			{
				path: '/register',
				name: 'register',
				component:Register
			}
		]
	})

	var App = {
		template:`
			<div>
				<!-- 2. 使用v-bind绑定,name的value必须是字符串 -->
				<router-link :to="{name:'login'}">登录</router-link>
				<router-link :to="{name:'register'}">注册</router-link>

				<!-- router-view, 路由组件的出口 -->
				<router-view></router-view>
			</div>
		`,
	}

路由范式,params和query使用

  1. xxx.html#/user/1, 相当于给了一个参数 params
  2. xxx.html#/user?userID=1, 表示查询,query

代码,属于声明式

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin:0;
		}
	</style>
</head>
<body>
<div id='app'>
</div>

<script type="text/javascript" src="./vue.js"></script>
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>

<script type="text/javascript">
	Vue.use(VueRouter)
	

	var USerParams = {
		template:`
			<div>我是用户1</div>
		`,
		created(){
			// 可以使用this.$route.params.userId拿到动态路由的参数
			console.log(this.$route);
			console.log(this.$router);
		},
	}
	var UserQuery = {
		template:`
			<div>我是用户2</div>
		`,
		created(){
			// 可以使用this.$route.query.userId拿到query的参数
			console.log(this.$route);
			console.log(this.$router);
		},
	}

	var router = new VueRouter({
		routes:[
			{
				// 1. 动态的路由参数,以:号开头。
				path: '/user/:userId',
				name: 'userp',
				component:USerParams
			},
			{
				// 2 query的书写
				path: '/user',
				name: 'userq',
				component:UserQuery
			}
		]
	})

	var App = {
		template:`
			<div>
				<!--3. 在链接的to属性中添加params键值对  -->
				<router-link :to="{name:'userp', params:{userId:1}}">用户1</router-link>
				<!--4. 在链接的to属性中添加params键值对  -->
				<router-link :to="{name:'userq', params:{userId:2}}">用户2</router-link>

				<router-view></router-view>
			</div>
		`,
	}

	new Vue({
		el:'#app',
		template:`<App />`,
		components:{
			App
		},
		// 4.添加router对象,key,value一样可以写一个,router:router等价于router
		router:router,
	})
</script>
</body>
</html>


图解 代码:
在这里插入图片描述

页面效果:
在这里插入图片描述

编程式导航

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin:0;
		}
	</style>
</head>
<body>
<div id='app'>
</div>

<script type="text/javascript" src="./vue.js"></script>
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>

<script type="text/javascript">
	Vue.use(VueRouter)
	

	var USerParams = {
		template:`
			<div>我是用户1</div>
		`,
		created(){
			// 可以使用this.$route.params.userId拿到动态路由的参数
			console.log(this.$route.params.userId);
			console.log(this.$router);
		},
	}
	var UserQuery = {
		template:`
			<div>我是用户2</div>
		`,
		created(){
			// 可以使用this.$route.query.userId拿到query的参数
			console.log(this.$route.query.userId);
			console.log(this.$router);
		},
	}

	var router = new VueRouter({
		routes:[
			{
				path: '/user/:userId',
				name: 'userp',
				component:USerParams
			},
			{
				path: '/user',
				name: 'userq',
				component:UserQuery
			}
		]
	})

	var App = {
		template:`
			<div>
				<button @click="paramsHandle">用户1</button>
				<button @click="queryHandle">用户2</button>
				<router-view></router-view>
			</div>
		`,
		methods:{
			paramsHandle(){
				// 编程式,name是命名路由的名字,params是参数
				this.$router.push({name:'userp', params:{userId:123}})
			},
			queryHandle(){
				this.$router.push({name:'userq', query:{userId:234}})
			}
		}
	}

	new Vue({
		el:'#app',
		template:`<App />`,
		components:{
			App
		},
		// 4.添加router对象,key,value一样可以写一个,router:router等价于router
		router:router,
	})
</script>

</body>
</html>

页面显示:
在这里插入图片描述

嵌套路由

一个router-view嵌套另外一个router-view.

需求:进入首页后,有两个按钮,点击音乐访问/home/music,点击电影访问/home/movie

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin:0;
		}
	</style>
</head>
<body>
<div id='app'>
</div>

<script type="text/javascript" src="./vue.js"></script>
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>

<script type="text/javascript">
	Vue.use(VueRouter)
	

	var Home = {
		template:`
			<div>
				<router-link to="/home/music">音乐</router-link>
				<router-link to="/home/movie">电影</router-link>
				<!-- Musci和Movie组件出口 -->
				<router-view></router-view>
			</div>
		`,
	}

	var Music = {
		template:`
			<div>我是音乐</div>
		`
	}

	var Movie = {
		template:`
			<div>我是电影</div>
		`
	}

	var router = new VueRouter({
		routes:[
			{
				path: '/home',
				name: 'home',
				component:Home,
				// 嵌套路由,会自动和/home拼接为/home/music,/home/movie
				children:[
					{
						path: 'music',
						component:Music
					},
					{
						path: 'movie',
						component:Movie
					}
				]
			},
			
		]
	})

	var App = {
		template:`
			<div>
				<router-link :to="{name:'home'}">首页</router-link>
				<!--首页组件出口  -->
				<router-view></router-view>
			</div>
		`,
		methods:{
		}
	}

	new Vue({
		el:'#app',
		template:`<App />`,
		components:{
			App
		},
		router:router,
	})
</script>

</body>
</html>

流程图解
在这里插入图片描述
页面效果
在这里插入图片描述

页面的改进:
1.在页面中访问首页,只显示首页,首页下面的内容没有显示
在这里插入图片描述
2.在点击首页的时候才会显示,首页下面的内容
在这里插入图片描述
3.希望在访问首页时,默认把音乐和电影两个链接显示出来
在路由配置对象中进行设置,添加一个路由,在访问/时重定向到子路由。

	var router = new VueRouter({
		routes:[
		 	// 添加一个路由 ,访问/时,重定向到/home
			{
				path: '/',
				redirect:'/home'
				// redirect:{name:'home'}  // 也可以是个对象
			},
			{
				path: '/home',
				name: 'home',
				component:Home,
				// 嵌套路由,会自动和/home拼接为/home/music,/home/movie
				children:[
					{
						path: 'music',
						component:Music
					},
					{
						path: 'movie',
						component:Movie
					}
				]
			},
			
		]
	})

4.希望在访问首页时,默认把音乐下面的内容展示出来。
在子路由中进行配置

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin:0;
		}
	</style>
</head>
<body>
<div id='app'>
</div>

<script type="text/javascript" src="./vue.js"></script>
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>

<script type="text/javascript">
	Vue.use(VueRouter)
	

	var Home = {
		template:`
			<div>
				<router-link to="/home/music">音乐</router-link>
				<router-link to="/home/movie">电影</router-link>
				<!-- Musci和Movie组件出口 -->
				<router-view></router-view>
			</div>
		`,
	}

	var Music = {
		template:`
			<div>我是音乐</div>
		`
	}

	var Movie = {
		template:`
			<div>我是电影</div>
		`
	}

	var router = new VueRouter({
		routes:[
			{
				path: '/',
				redirect:'/home'
			},
			{
				path: '/home',
				name: 'home',
				component:Home,
				children:[
					{
						// 当访问/home时,Home组件中template中的出口是不会渲染任何内容的。这是因为没有 匹配到合适的子路由
						path:'',  // 表示匹配到/home
						component: Music  // 匹配到这个路由时,直接 渲染Music组件到路由出口
					},
					{
						path: 'music',
						component:Music
					},
					{
						path: 'movie',
						component:Movie
					}
				]
			},
			
		]
	})

	var App = {
		template:`
			<div>
				<router-link :to="{name:'home'}">首页</router-link>
				<!--首页组件出口  -->
				<router-view></router-view>
			</div>
		`,
		methods:{
		}
	}

	new Vue({
		el:'#app',
		template:`<App />`,
		components:{
			App
		},
		router:router,
	})
</script>

</body>
</html>

图解代码:
在这里插入图片描述
页面显示:
在这里插入图片描述

动态路由匹配

动态修改路由加载的是同一个组件,展示不同的数据。

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin:0;
		}
	</style>
</head>
<body>
<div id='app'>
</div>

<script type="text/javascript" src="./vue.js"></script>
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>

<script type="text/javascript">
	Vue.use(VueRouter)
	
	var Timeline =  {
		template:`
			<div>
				<router-link :to="{name:'comdes', params:{id:'android'}}">安卓</router-link>
				<router-link :to="{name:'comdes', params:{id:'frontend'}}">前端</router-link>
				<router-view></router-view>
			</div>
		`
	}

	var Pins =  {
		template:`
			<div>我是沸点</div>
		`
	}

	// 共同的子组件
	var ComDesc = {
		data(){
			return {
				msg: ''
			}
		},
		template:`
			<div>公共组件{{msg}}</div>
		`,
		watch: {
			// 2.检测路由对象的变化。to子去哪个路由,from是从哪个路由来
		    $route(to, from) {
		      // 对路由变化作出响应...
		      console.log(to)
		      console.log(from)
		      // 拿到params参数
		      this.msg = to.params.id
			}
		}
	}

	var router = new VueRouter({
		routes:[
			{
				path: '/',
				redirect:'/Timeline'
			},
			{
				path: '/timeline',
				component:Timeline,
				children:[
					{
						path: '',
						component: ComDesc
					},
					{
						// 1.多个router-link匹配到此路由,渲染相同的组件。
						path: '/timelin/:id',
						name: 'comdes',
						component: ComDesc
					}
				]

			},
			{
				path: '/pins',
				component:Pins
			},
		]
	})

	var App = {
		template:`
			<div>
				<router-link to="/timeline">首页</router-link>
				<router-link to="/pins">沸点</router-link>
				<!--首页组件出口  -->
				<router-view></router-view>
			</div>
		`,
		methods:{
		}
	}

	new Vue({
		el:'#app',
		template:`<App />`,
		components:{
			App
		},
		router:router,
	})
</script>

</body>
</html>

为什么不适用声明周期钩子函数created来检测,是因为官网如下所说:

当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象:

当router切换时,都是同一个组件,不会再重复的销毁再创建,所以created钩子函数只会被调用一次。

在这里插入图片描述

keep-alive在路由中的使用

内部组件,保持缓存活跃的状态。保持原来组件的一个缓存。
切换路由的时候,会加载不同的组件,也就意味着有组件的创建和销毁的过程。

将我们的组件出口用<keep-alilve><router-view></router-view></keep-alive>包起来就行了.
生命流程中走激活和停用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值