11.初步使用vue-router

vue-router:

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。

https://router.vuejs.org/zh/guide/

起步

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>start</title>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
	<div id="app">
		<h1>{{msg}}</h1>
		<button v-on:click='showRouter'>$router 访问路由器</button>
		<button v-on:click='showRoute'>$route 访问当前路由</button>
		<div>
			<!-- 使用 router-link 组件来导航. -->
			<!-- 通过传入 `to` 属性指定链接. -->
			<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
			<router-link to="/foo">Go to Foo</router-link>
			<router-link to="/bar">Go to Bar</router-link>
		</div>
		<!-- 路由出口 -->
		<!-- 路由匹配到的组件将渲染在这里 -->
		<router-view>
			
		</router-view>
	</div>
	<script type="text/javascript">
		Vue.config.productionTip = false;
		// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)

		// 1. 定义 (路由) 组件。
		// 可以从其他文件 import 进来
		const Foo = { template: '<div>foo</div>' }
		const Bar = { template: '<div>bar</div>' }

		// 2. 定义路由
		// 每个路由应该映射一个组件。 其中"component" 可以是
		// 通过 Vue.extend() 创建的组件构造器,
		// 或者,只是一个组件配置对象。
		// 我们晚点再讨论嵌套路由。
		const routes = [
			{ path: '/foo', component: Foo },
			{ path: '/bar', component: Bar }
		]

		// 3. 创建 router 实例,然后传 `routes` 配置
		// 你还可以传别的配置参数, 不过先这么简单着吧。
		const router = new VueRouter({
			routes // (缩写) 相当于 routes: routes
		})

		// 4. 创建和挂载根实例。
		// 记得要通过 router 配置参数注入路由,
		// 从而让整个应用都有路由功能
		const app = new Vue({
			router: router,
			data(){
				return {
					msg: 'hello router'
				}
			},
			methods: {
				showRouter(){
					console.log('函数 showRouter')
					console.log(this.$router);
				},
				showRoute(){
					console.log('函数 showRoute')
					console.log(this.$route);
				}
			}
		}).$mount('#app');

		// 现在,应用已经启动了!
	</script>
</body>
</html>

动态路由匹配

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>1.dynamic-router</title>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
	<div id="app">
		<h1>{{msg}}</h1>
		<div>
			<router-link to="/user/foo">Go to Foo</router-link>
			<router-link to="/user/bar">Go to Bar</router-link>
		</div>
		<router-view>
			
		</router-view>
	</div>
	<script type="text/javascript">
		Vue.config.productionTip = false;

		const router = new VueRouter({
				routes: [
						// 动态路径参数 以冒号开头
						{
							path: '/user/:id',
							component: {
								template: '<div>User - id: {{ $route.params.id }}</div>',
							}
						}
				],
		});

		const app = new Vue({
			router: router,
			data(){
				return {
					msg: 'hello dynamic-router'
				}
			},
			methods: {
				showRouter(){
					console.log('函数 showRouter')
					console.log(this.$router);
				},
				showRoute(){
					console.log('函数 showRoute')
					console.log(this.$route);
				}
			}
		}).$mount('#app');
	</script>
</body>
</html>

嵌套路由

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>2.nested-router.html</title>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
	<div id="app">
		<h1>{{msg}}</h1>
		<div>
			<router-link to="/user/door">Go to door</router-link>
		</div>
		<router-view></router-view>
	</div>
	<script type="text/javascript">
		Vue.config.productionTip = false;
		const User = {
			template: `
			<div class="user">
				<h2>User {{ $route.params.id }}</h2>
				<router-link to="/user/door/profile">profile</router-link>
				<router-link to="/user/door/posts">posts</router-link>
				<router-view></router-view>
			</div>
			`
		}
		const router = new VueRouter({
			routes: [
				{
					path: '/user/:id', component: User,
					children: [
						{
							// 当 /user/:id/profile 匹配成功,
							// UserProfile 会被渲染在 User 的 <router-view> 中
							path: 'profile',
							component: {
								template: `<p>我是嵌套的路由组件 profile !</p>`
							}
						},
						{
							// 当 /user/:id/posts 匹配成功
							// UserPosts 会被渲染在 User 的 <router-view> 中
							path: 'posts',
							component: {
								template: `<p>我是嵌套的路由组件 posts !</p>`
							}
						}
					]
				}
			]
		})
		const app = new Vue({
			router: router,
			data(){
				return {
					msg: 'hello nested-router'
				}
			},
			methods: {
				showRouter(){
					console.log('函数 showRouter')
					console.log(this.$router);
				},
				showRoute(){
					console.log('函数 showRoute')
					console.log(this.$route);
				}
			}
		}).$mount('#app');
	</script>
</body>
</html>

命名路由

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>3.name-router</title>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
	<div id="app">
		<h1>{{msg}}</h1>
		<router-link v-bind:to="{name:'homeName', path:'/home'}" >Home</router-link>
		<router-view></router-view>
	</div>
	<script type="text/javascript">
		Vue.config.productionTip = false;
		const router = new VueRouter({
			routes: [
				{
					path: '/home',
					component: {
						template: '<div>匹配 home 路径的组件</div>',
					}
				},
				{
					path: '/home',
					name: 'homeName',
					component: {
						template: '<div>匹配 home 路径, name 是 homeName 的组件</div>',
					}
				}
			]
		})
		const app = new Vue({
			router: router,
			data(){
				return {
					msg: 'name-router'
				}
			},
		}).$mount('#app');
	</script>
</body>
</html>

命名视图

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>4.name-view</title>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
	<div id="app">
		<h1>{{msg}}</h1>
		<router-link to="/home" >Home</router-link>
		<router-view></router-view>
		<router-view name='home'></router-view>
		<router-view name='test'></router-view>
	</div>
	<script type="text/javascript">
		Vue.config.productionTip = false;
		const router = new VueRouter({
			routes: [
				{
					path: '/home',
					components: {
						default: {
							template: '<div>默认的组件</div>',
						},
						home: {
							template: '<div>匹配 home 路径 home name 的组件</div>',
						},
						test: {
							template: '<div>匹配 home 路径 test name 的组件</div>',
						}
					}
				}
			]
		})
		const app = new Vue({
			router: router,
			data(){
				return {
					msg: 'name-view'
				}
			},
		}).$mount('#app');
	</script>
</body>
</html>

重定向

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>5.redirect</title>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
	<div id="app">
		<h1>{{msg}}</h1>
		<router-link to="/home" >Home</router-link>
		<router-view></router-view>
		<router-view name='home'></router-view>
	</div>
	<script type="text/javascript">
		Vue.config.productionTip = false;
		const router = new VueRouter({
			routes: [
				{
					path: '/home',
					components: {
						default: {
							template: '<div>默认的组件</div>',
						},
						home: {
							template: '<div>匹配 home 路径的组件</div>',
						},
					},
					redirect: {
						 name: '/home/index',
					}
				},
				{
					name: '/home/index',
					path: '/index',
					components: {
						default: {
							template: '<div>重定向的组件</div>',
						},
						home: {
							template: '<div>重定向 home 的组件</div>',
						},
					},
				}
			]
		})
		const app = new Vue({
			router: router,
			data(){
				return {
					msg: 'redirect'
				}
			},
		}).$mount('#app');
	</script>
</body>
</html>

别名:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>6.alias</title>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
	<div id="app">
		<h1>{{msg}}</h1>
		<router-link to="/home" >Home</router-link>
		<router-link to="/alias" >Alias</router-link>
		<router-view></router-view>
		<router-view name='home'></router-view>
	</div>
	<script type="text/javascript">
		Vue.config.productionTip = false;
		const router = new VueRouter({
			routes: [
				{
					alias: '/alias',
					path: '/home',
					components: {
						default: {
							template: '<div>默认的组件</div>',
						},
						home: {
							template: '<div>匹配 home 路径的组件</div>',
						},
					},
				},
			]
		})
		const app = new Vue({
			router: router,
			data(){
				return {
					msg: 'alias'
				}
			},
		}).$mount('#app');
	</script>
</body>
</html>

路由组件传参:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>7.props</title>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
	<div id="app">
		<h1>{{msg}}</h1>
		<router-link to="/home/props" >Home</router-link>
		<router-view></router-view>
	</div>
	<script type="text/javascript">
		Vue.config.productionTip = false;
		const router = new VueRouter({
			routes: [
				{
					path: '/home/:homeName',
					component: {
						props: ['homeName'],
						template: '<div>home {{ homeName }}</div>'
					},
					props: true,
					// props: {
					// 	homeName: '静态数据,不是路径'
					// },
					// props: function(){
					// 	return {
					// 		homeName: '函数返回的数据'
					// 	}
					// }
				}
			]
		})
		const app = new Vue({
			router: router,
			data(){
				return {
					msg: 'props'
				}
			},
		}).$mount('#app');
	</script>
</body>
</html>

直接true

props: true,

对象:

props: {
	homeName: '静态数据,不是路径'
},

函数:

props: function(){
	return {
		homeName: '函数返回的数据'
	}
}

导航守卫:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>8.guard</title>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
	<div id="app">
		<h1>{{msg}}</h1>
		<router-link to="/home/aaa" >Home/aaa</router-link>
		<router-link to="/home/bbb" >Home/bbb</router-link>
		<router-link to="/test" >Test</router-link>
		<router-view></router-view>
	</div>
	<script type="text/javascript">
		Vue.config.productionTip = false;
		const router = new VueRouter({
			routes: [
				{
					path: '/home/:id',
					component: {
						template: '<div>匹配 home 路径的组件 {{$route.params.id}}</div>',
						beforeRouteEnter (to, from, next) {
								// 在渲染该组件的对应路由被 confirm 前调用
								// 不!能!获取组件实例 `this`
								// 因为当守卫执行前,组件实例还没被创建
								console.log('home routes beforeRouteEnter')
								console.log('to:', to);
								console.log('from:', from);
								console.log('next:', next);
								next();
						},
						beforeRouteUpdate (to, from, next) {
								// 在当前路由改变,但是该组件被复用时调用
								// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
								// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
								// 可以访问组件实例 `this`
								console.log('home routes beforeRouteUpdate')
								console.log('to:', to);
								console.log('from:', from);
								console.log('next:', next);
								next();
						},
						beforeRouteLeave (to, from, next) {
								// 导航离开该组件的对应路由时调用
								// 可以访问组件实例 `this`
								console.log('home routes beforeRouteLeave')
								console.log('to:', to);
								console.log('from:', from);
								console.log('next:', next);
								next();
						}
					}
				},
				{
					path: '/test',
					component: {
						template: '<div>匹配 test 路径的组件</div>',
					},
					beforeEnter: (to, from, next) => {
						console.log('test beforeEnter')
						console.log('to:', to);
						console.log('from:', from);
						console.log('next:', next);
						next();
					}
				}
			]
		});
		router.beforeEach(function(to, from, next) {
			console.log('beforeEach to:', to);
			console.log('beforeEach from:', from);
			console.log('beforeEach next:', next);
			next();
		});
		router.afterEach((to, from) => {
			console.log('afterEach to:', to);
			console.log('afterEach from:', from);
		})
		const app = new Vue({
			router: router,
			data(){
				return {
					msg: 'guard'
				}
			},
		}).$mount('#app');
	</script>
</body>
</html>

路由元信息:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>meta</title>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
	<div id="app">
		<h1>{{msg}}</h1>
		<div>
			<router-link to="/user/foo">Go to Foo</router-link>
			<router-link to="/user/bar">Go to Bar</router-link>
		</div>
		<router-view></router-view>
	</div>
	<script type="text/javascript">
		Vue.config.productionTip = false;

		const router = new VueRouter({
				routes: [
						{
							path: '/user/:id',
							component: {
								template: '<div>User - id: {{ $route.params.id }}</div>',
							},
							meta: { requiresAuth: true }
						}
				],
		});
		router.beforeEach((to, from, next) => {
			console.log(to.meta)
			next()
		})
		const app = new Vue({
			router: router,
			data(){
				return {
					msg: 'meta'
				}
			},
		}).$mount('#app');
	</script>
</body>
</html>

小结:

可以初步的看出来,vue-router,通过<router-link>标签实现路由的跳转,<router-view>实现页面的显示。在js中,通过VueRouter实例对象注册路由信息。

可以把vue-router看作是动态组件地显示,只是显示依据主要是路径。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值