@[TOC]Vue 中路由 Router 的使用
什么是路由
- 后端路由: 对于普通的网站,所有的超链接都是 URL 地址,所有的 URL 地址都对应服务器上对应的资源;
- 前端路由:对于单页面应用程序来说,主要通过 URL 中的 hash(#号)来实现不同页面之间的切换,同时,hash 有一个特点:HTTP 请求中不会包含 hash 相关内容;所以,单页面应用程序中的页面跳转主要用 hash 实现;
- 在单页面应用程序中,这种通过 hash 改变来切换页面方式,称作前端路由(区别于后端路由)。
在 Vue 中使用 Router
- 引用 vue-router.js 这个包(可在网上直接下载 vue-router包);
- 创建一个路由对象,当导入 vue-router 包之后,在 window 全局对象中,就有一个路由的构造函数 VueRouter(可以直接 new 创建);
- 使用 VueRouter 实例下的 routes 属性指定路由匹配规则(这时候要创建组件);
每个路由规则,都是一个对象,这个规则对象身上有两个必须的属性:
属性1:path 表示监听哪个路由链接地址;
属性2:component 表示如果路由是前面匹配到的 path,则展示 component 属性对应的组件;
注意:component 的属性值必须是一个组件模板对象,不能是组件的引用名称。
- 将路由规则对象,注册到 Vue 实例,用来监听 URL 变化,然后展示对应的组件;
- 要想在页面显示组件,在 html 中还要写上 vue-router 提供的 router-view 元素,这是专门用来当做占位符的,将来路由规则匹配到的组件,就会展示到 router-view 中(可认为是个占位符)。
代码示例:路由 router 的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src='vue.js'></script>
<!--1. 安装 vue-router 路由模块(注意顺序)-->
<script src="vue-router.js"></script>
<style>
body{
font-size:36px;
color:#fff;
}
.router-link-active,.myactive{ /*高亮显示*/
color:red;
font-weight:800;
font-size:50px;
}
.v-enter,.v-leave-to{ /*为路由添加动画*/
opacity:0;
transform:translateX(100px)
}
.v-enter-active,.v-leave-active{
transition:all .6s;
}
</style>
</head>
<body>
<div id="app">
<!-- router-link 默认渲染为一个 a 标签,可通过 tag 属性更改渲染的标签 -->
<!-- <router-link to='/login?id=1' tag='span'>login</router-link> -->
<router-link to='/login' tag='span'>login</router-link>
<router-link to='/register' tag='span'>register</router-link>
<router-view></router-view><!-- 5.占位符、容器 -->
</div>
</body>
</html>
<script>
//3.创建组件模板对象
//可以在任何组件内通过 this.$router 访问路由器,也可以通过 this.$route 访问当前路由
var login = {
template:'<h1>login component</h1>',
}
}
var register = {
template:'<h1>register component</h1>'
}
//2.创建一个路由对象,导入 vue-router 包之后,在 window 全局对象中,就有一个路由的构造函数 -> VueRouter
//在 new 路由对象的时候,可以为构造函数传递一个配置对象
var router = new VueRouter({
routes:[ //路由匹配规则
//注意:component 的属性值必须是一个组件模板对象,不能是组件的引用名称
{path:'',redirect:'/login'}, //redirect 重定向,默认显示 login 组件
{path:'/login',component:login},
{path:'/register',component:register}
]
})
new Vue({
el:'#app',
data:{},
methods:{},
router //router:router 的简写
//4.将路由规则对象,注册到 Vue 实例,用来监听 URL 变化,然后展示对应的组件
});
</script>
路由 router-link
路由还提供了 router-link 元素,使用 router-link 组件来导航,通过传入 to 属性指定链接(注:该元素默认会渲染一个a标签,可通过 tag 属性更改渲染的标签)。
注意:当 router-link 对应的路由匹配成功,将自动设置 class 属性值 .router-link-active。故我们还可以给这个类添加样式,如:高亮显示。
注释:如果在路由中,使用查询字符串,则不需要修改路由规则的 path 属性
路由 redirect 重定向
“重定向”的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b;(可用作根路径默认显示主页或者其他组件)
重定向是通过 routes 配置来完成,下面例子是从 /login 重定向到 /register :
var router = new VueRouter({
routes: [
{ path: '/login', redirect: '/register' }
]
})
重定向的目标也可以是一个命名的路由:
var router = new VueRouter({
routes: [
{ path: '/login', redirect: { name: 'login' }}
]
})
甚至是一个方法,动态返回重定向目标:
var router = new VueRouter({
routes: [
{ path: '/login', redirect: to => {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}}
]
})
路由嵌套
使用路由 children 属性实现路由嵌套。
子路由的嵌套,路径不能有 ‘/’,否则永远以根路径开始请求。
代码示例:
<body>
<div id="app">
<router-link to='/account'>Account</router-link>
<router-view></router-view>
</div>
<template id='tmpl'>
<div><!-- 必须有一个 根路径 -->
<h1>Account component</h1>
<router-link to='/account/login'>login</router-link>
<router-link to='/account/register'>register</router-link>
<router-view></router-view>
</div>
</template>
</body>
<script>
var account = {
template:'#tmpl'
}
var login = {
template:'<h3>login</h3>'
}
var register = {
template:'<h3>register</h3>'
}
var router = new VueRouter({
routes:[
{
path:'/account',
component:account,
children:[ //子路由的嵌套,路径不能有 ‘/’,否则永远以根路径开始请求
{path:'login',component:login},
{path:'register',component:register},
]
},
]
})
new Vue({
el:'#app',
data:{},
methods:{},
router
})
</script>
路由传参
通过 this.$ route 访问路由器,也可以通过 this.$ route 访问当前路由。
使用 query 传参
在 console 里可以输出看到 route 下的属性 query,可通过点的方式访问。(this.$route.query)
代码示例:
<div id="app">
<!-- 如果在路由中,使用查询字符串,则不需要修改路由规则的 path 属性 -->
<router-link to='/login?id=12' tag='span'>login</router-link>
<router-link to='/register' tag='span'>register</router-link>
<router-view></router-view><!-- 占位符、容器 -->
</div>
<script>
//组件模板对象
var login = {
// template:'<h1>login component --- {{$route.query.id}}</h1>',
template:'<h1>login component</h1>',
created(){ //组件的生命周期钩子函数
console.log(this.$route.query.id)
//获取到查询字符串的参数
}
}
var register = {
template:'<h1>register component</h1>'
}
//创建一个路由对象
var router = new VueRouter({
routes:[ //路由匹配规则
{path:'/login',component:login},
{path:'/register',component:register}
]
})
new Vue({
el:'#app',
data:{},
methods:{},
router //将路由规则对象,注册到 Vue 实例,用来监听 URL 变化,然后展示对应的组件
});
</script>
使用 query 传参的好处是:如果在路由中,使用查询字符串传参,则不需要修改路由规则的 path 属性。
使用 params 传参
在 console 里可以输出看到 route 下的属性 params,可通过点的方式访问。(this.$route.params)
代码示例:
<div id="app">
<router-link to='/login?12' tag='span'>login</router-link>
<router-link to='/register' tag='span'>register</router-link>
<router-view></router-view><!-- 占位符、容器 -->
</div>
<script>
//组件模板对象
var login = {
// template:'<h1>login component --- {{$route.query.id}}</h1>',
template:'<h1>login component</h1>',
created(){ //组件的生命周期钩子函数
console.log(this.$route.params.id)
}
}
var register = {
template:'<h1>register component</h1>'
}
//创建一个路由对象
var router = new VueRouter({
routes:[ //路由匹配规则
{path:'/login/:id',component:login},
{path:'/register',component:register}
]
})
new Vue({
el:'#app',
data:{},
methods:{},
router
});
</script>
使用 params 传参,需在 routes 匹配规则的 path 属性写一个占位符,然后在 router-link 元素 进行传参解析(这里必须传参,否则匹配不到路由规则),这时就可用 this.$route.params 方式使用传过来的参数。
使用命名视图路由实现经典布局
使用元素中的 name 属性实现命名视图。
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>命名视图</title>
<script src="vue.js"></script>
<script src="vue-router.js"></script>
<style>
body{
font-size: 30px;
color: #fff;
}
h1{
margin: 0
}
.head{
height: 100px;
background: orange;
text-align: center;
line-height: 100px;
}
.container{
display: flex;
height: 800px;
text-align: center;
line-height: 800px;
}
.side{
background: lightblue;
flex:3;
}
.main{
background: pink;
flex:7;
}
</style>
</head>
<body>
<div id="app">
<router-view></router-view>
<div class="container">
<!-- 命名视图 name属性 -->
<router-view name='sidebar'></router-view>
<router-view name='main'></router-view>
</div>
</div>
</body>
</html>
<script>
var header = {
template:'<h1 class="head">Header Area</h1>'
}
var sidebar = {
template:'<h1 class="side">Sidebar Area</h1>'
}
var main = {
template:'<h1 class="main">Main Area</h1>'
}
var router = new VueRouter({
routes:[
{path:'',components:{'default':header,'sidebar':sidebar,'main':main}}
]
})
var vm = new Vue({
el:'#app',
data:{},
methods:{},
router
})
</script>
命名视图的 name 属性值是一个字符串不是一个变量,只有用事件绑定属性 v-bind 的属性值才是一个变量,要想变成字符串需加引号。