8. Vue - Router
一、Vue Router 的使用
JavaScript:
1.创建组件:创建单页面应用需要渲染的组件
2.创建路由:创建VueRouter实例
3.映射路由:调用VueRouter实例的map方法
4.启动路由:调用VueRouter实例的start方法
HTML:
1.使用v-link指令
2.使用<router-view>标签
router.redirect:
1.应用在首次运行时右侧是一片空白,应用通常都会有一个首页,例如:Home页。
2.使用router.redirect方法将根路径重定向到/home路径:
router.redirect({'/': '/home'})
router.redirect 方法用于为路由器定义全局的重定向规则,全局的重定向会在匹配当前路径之前执行。
执行过程:
当用户点击v-link指令元素时,我们可以大致猜想一下这中间发生了什么事情:
1.vue-router首先会去查找v-link指令的路由映射
2.然后根据路由映射找到匹配的组件
3.最后将组件渲染到<router-view>标签
1. 引入Vue和Vue-Router插件
<script src="vue.js"></script>
<script src="vue-router.js"></script>
2. HTML
<div id="box">
</div>
<!--定义模版-->
<template id="a">
<div>
第一个router
</div>
</template>
<template id="b">
<div>
第二个router
</div>
</template>
3. js
let routes = [
{
path:'/home',
component:{template:'#a'},
},
{
path:"/two",
component:{template:"#b"}
},
];
// 定义路由组件
let router = new VueRouter({
routes
});
// 定义路由
new Vue({
el:"#box",
router,
})
4. 将模板增添链接
<div id="box">
<router-link to="/one">One</router-link>
<router-link to="/two">Two</router-link>
<router-view></router-view>
</div>
< router-link > 默认会被渲染成一个 <a> 标签 >>>to=""为我们定义的路由
< router-view > 路由匹配到的组件将渲染在这里
5. 简单示例
<div id="app">
<h1>路飞学城</h1>
<!--<router-link to="/home">首页</router-link>-->
<!--<router-link to="/course">免费课程</router-link>-->
<!-- 命名路由,to前要加冒号 -->
<router-link :to="{name:'home'}">首页</router-link>
<router-link :to="{name:'course'}">免费课程</router-link>
<!-- 路由出口 -->
<router-view></router-view>
</div>
<script>
let Home = {
template: `
<div>
<h1>首页</h1>
</div>`,
};
let Course = {
template: `
<div>
<h1>免费课程</h1>
</div>`,
};
let router = new VueRouter({
mode: 'history',
routes: [
// 路径重定向
{path: '', redirect: '/home'},
// 命名路由
{path: '/home', name: 'home', component: Home},
{path: '/course', name: 'course', component: Course},
]
});
let app = new Vue({
el: '#app',
router: router,
})
</script>
备注:mode: 'history' =>默认是hash,但是写上这个后就会出现url问题
二、补充知识
1、Vue Router定义
对于Vue这类渐进式前端开发框架,为了构建SPA(单页面应用),需要引入前端路由系统(Vue-Router)。前端路由的核心——改变视图的同时不会向后端发出请求。
2、浏览器提供了两种支持(hash/history)
(1) hash —— 即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。
比如这个 URL:http://www.abc.com/#/hello,hash 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
(2) history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)
(3) 总结
这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。hash 模式和 history 模式都属于浏览器自身的特性,Vue-Router 只是利用了这两个特性(通过调用浏览器提供的接口)来实现前端路由。
hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.abc.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.abc.com/book/id。如果后端缺少对 /book/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
3. router-link
// 字符串
<router-link to="apple"> to apple</router-link>
// 对象
<router-link :to="{path:'apple'}"> to apple</router-link>
// 命名路由
<router-link :to="{name: 'applename'}"> to apple</router-link>
//直接路由带查询参数query,地址栏变成 /apple?color=red
<router-link :to="{path: 'apple', query: {color: 'red' }}"> to apple</router-link>
// 命名路由带查询参数query,地址栏变成/apple?color=red
<router-link :to="{name: 'applename', query: {color: 'red' }}"> to apple</router-link>
//直接路由带路由参数params,params 不生效,如果提供了 path,params 会被忽略
<router-link :to="{path: 'apple', params: { color: 'red' }}"> to apple</router-link>
// 命名路由带路由参数params,地址栏是/apple/red
<router-link :to="{name: 'applename', params: { color: 'red' }}"> to apple</router-link>
4. router.push(...)
// 字符串
router.push('apple')
// 对象
router.push({path:'apple'})
// 命名路由
router.push({name: 'applename'})
//直接路由带查询参数query,地址栏变成 /apple?color=red
router.push({path: 'apple', query: {color: 'red' }})
// 命名路由带查询参数query,地址栏变成/apple?color=red
router.push({name: 'applename', query: {color: 'red' }})
//直接路由带路由参数params,params 不生效,如果提供了 path,params 会被忽略
router.push({path:'applename', params:{ color: 'red' }})
// 命名路由带路由参数params,地址栏是/apple/red
router.push({name:'applename', params:{ color: 'red' }})
5. 备注
(1) 关于带参数的路由总结
(1)无论是直接路由“path"还是命名路由“name”,带查询参数query,地址栏会变成“/url?查询
(2)参数名:查询参数值“;
(3)直接路由“path" 带路由参数params params 不生效;
(4)命名路由“name" 带路由参数params 地址栏保持是“/url/路由参数值”;
(2) 设置路由map里的path值
带路由参数params时,路由map里的path应该写成: path:'/apple/:color' ;
带查询参数query时,路由map里的path应该写成: path:'/apple' ;
(3) 获取参数方法
在组件中: {{$route.params.color}}
在js里: this.$route.params.color
6. vue中从一个页面传参到另一个页面
(1) 首先在home.vue中定义
updates(id){
this.$router.push({
path:'/world',
name:'world',
params:{
id : id
}
})
}
(2) 在world.vue中定义
export default {
name: '',
data () {
return {
id: ''
}
},
created(){
this.getParams()
},
methods: {
getParams () {
// 取到路由带过来的参数
var routerParams = this.$route.params.id
// 将数据放在当前组件的数据内
this.id = routerParams
}
},
watch: {
// 监测路由变化,只要变化了就调用获取路由参数方法将数据存储本组件即可
'$route': 'getParams'
}
}
三、Vue嵌套路由
1. 定义
嵌套路由是一个场景的需求,假设用户能够通过路径 /home/news 和 /home/mesages访问一些内容,一个路径映射一个组件,访问这两个路径也会分别渲染两个组件。
2. 示例
let UserInfo = {
template: `
<div>
这是用户信息
</div>`
};
let UserPost = {
template: `
<div>
这是用户请求
</div>`
};
// 2. 定义路由
let router = new VueRouter({
// mode: 'history',
routes: [
{
path: '/user/:id',
name: 'user',
component: User,
children:[
{path:'userinfo', component: UserInfo},
{path:'userpost', component: UserPost},],
},
]
});
四、路由对象
在使用了 vue-router 的应用中,路由对象会被注入每个组件中,赋值为 this.$route ,
并且当路由切换时,路由对象会被更新。
路由对象暴露了以下属性:
1.$route.path
字符串,等于当前路由对象的路径,会被解析为绝对路径,如 "/home/news" 。
2.$route.params
对象,包含路由中的动态片段和全匹配片段的键值对
3.$route.query
对象,包含路由中查询参数的键值对。例如,对于/home/news/detail/01?favorite=yes
会得到$route.query.favorite == 'yes' 。
4.$route.router
路由规则所属的路由器(以及其所属的组件)。
5.$route.matched
数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
6.$route.name
当前路径的名字,如果没有使用具名路径,则名字为空。
-
this.$router 对应的是当前app的路由对象
-
this.$route 对应的是当前的路由信息
-
路由切换的监听需用到watch侦听器
// 怎么查看每一次路由切换之后的当前路由信息呢?
watch: {
'$route': function (to, from) {
console.log(to); // 要切换到的路由信息
console.log(from); // 切换前的路由信息
// ajax 请求数据
// this.data.courseList
}
}
五、动态路由匹配
1. HTML
<div id="app">
<router-link :to="{name:'user', params:{id: 10}}">alex</router-link>
<router-view></router-view>
</div>
2. js
let User = {
template: `
<div>
<h1>这是{{ this.$route.params.id }}的个人中心页面</h1>
<p>当前路由的query信息{{ this.$route.query.key }}</p>
</div>`,
};
let router = new VueRouter({
// mode: 'history',
routes: [
// 添加参数冒号
// id(id可随便取名,标识),这个属性id可以在$route.params.id中获取
{path: '/user/:id', name: 'user', component: User},
]
});
let app = new Vue({
el: '#app',
data: {
},
router: router,
})
3. 记住两个参数
(1)this.$route.params获取URL中的参数
(2)this.$route.query获取URL中的查询参数
六、编程式导航
// 用代码控制页面跳转;定义课程页组件
let Course = {
template: `<div>
<h1>这是免费课程页面!</h1>
<button v-on:click="toHome">返回主页</button>
</div>`,
methods: {
toHome(){
// 编程式导航 (用代码控制页面跳转)
this.$router.push({name: 'home'})
}
}
};