Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
上面是vue-router官方的介绍,接下来我总结一下,自己平时用的vue-router的相关知识,适合入门级别的小白白们,高手请绕(饶)过
在使用vue-router之前,我们首先要把他整合到vue脚手架中,
(注意:本文的讲解基础是已经默认你安装好了vue-cli那一套东西)
vue-router 安装
npm install vue-router --save
在 src/router/index.js
文件下写入以下代码
import Vue from 'vue'
import VueRouter from 'vue-router'
//在vue中注册VueRouter
Vue.use(VueRouter);
//导入路由映射的组件
//普通导入方式
import comA from '@components/comA'
//需要懒加载的导入方式(所谓懒加载就是说,一开始不会加载所有的资源导致等待时间太长,而是当你切换导航的时候,相关组件里面的资源会陆续加载)
const comB = resolve=>require(['@components/comB'],resolve);
//然后写出路由映射关系
const routes = [
{
path:'/',
name:'home',
component:home,
},
{
path:'/about',
name:'about',
component:about,
children:[
{
path:'aboutA' //其实相当于 path:'/about/aboutA'
},{
path:'aboutB',
}
]
}
]
这就是比较简单和比较全的结构了,除去(参数和钩子,后面讲)。
写完映射关系,然后创建router实例,并且吧映射关系传进去
const router = new VueRouter({
routes
})
//需要注意的是,全局路由钩子就是要写在router实例上的,如下
router.beforeEach((to, from, next)=>{
...
next();
})
接下来,我们来看看vue-router的模式
vue-router默认使用的是hash模式,就是在路由跳转的时候,会有很多 #
,看起来不太美观,因此我们可以使用 history模式
,这种模式充分利用了 history.pushState
API来完成URL跳转而无需重新加载页面,从而提高了用户体验。但是,当你直接访问 www.root.com/home/page1
的时候,浏览器就会真的去请求该地址,如果后端没有相关的配置,那么就会返回404,就很尴尬了,所以一定要和后端配合好。
模式基本的样子就是下面的样子
const router = new VueRouter({
mode:"history",
routes
})
路由传参
一般路由有两种传参方式,分为 params
和 query
,先看看params吧,就用官网的例子吧
const User = {
template: '<div>{{$route.params.id}}</div>'
}
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})
在组件内使用$route会使 组件与之高度耦合,从而组件只能在特定的URL上使用,他的灵活性受到了限制,因此可以使用props
使他们解耦,
const User = {
props:['id'],
template:`<div>{{id}}</div>`
}
const router = new VueRouter({
routes:[
{
path:'/user/:id',
component:User,
props:true
},
//对于包含命名视图的路由,你必须分别为每一个命名路由添加 props 选项,如下
{
path:'/user/:id',
components:{default:User,sidebar:SideBar},
props:{default:true,sidebar:false}
}
]
})
这样一来就极大的增加了组件的灵活性,更加易于重用和测试
params 和 query
query
是这样用的
//传参
this.$router.push({
name:'home',
query:{
id:id
}
})
//接受参数
this.route.query.id
params
和query十分相似,
//传参
this.$router.push({
name:'home',
params:{
id:id
}
})
//接受参数
this.route.params.id
这里有一点是需要注意的,那就是使用 params的时候,是不可以使用path的,因为params本身就是path动态路径的构成元素,这样会发生矛盾。
为了保持一致性,query 和 params传参的时候,都尽量 使用nama来进行区分。
参数的位置
一般情况下this.$router.push
和router-link
里面的to
的参数类型是一模一样的。如下
<router-link to:"/home"></router-link>
//相当于
this.$router.push("/home");
{
name:"home",
path:'/home/:id',
componet:Home
}
<router-link to:"{name:"home",params:{id:"lala"}}"
//相当于
this.$router.push({
name:"home",
params:{
id:"lala"
}
})
以上就是 to
和this.$router.push
参数一直的说明,接下来 我们就 系统的看一下,路由钩子
;
路由钩子
全局路由钩子
beforeEach
and afterEach
const router = new VueRouter({
...
})
//需要注意的是,全局路由钩子,是路由实例上的,也就是上面的那个 router上的,不要弄混哦
router.beforeEach((to, from, next)=>{
// to 将要到达的路由对象
// from 目标路由对象
// next()进行下一步
// next(false) 中断当前的跳转,一般用于 提醒用户是否确认进入某页面,用户取消
//next('/') 或者 next({name:"home",params:{}})
})
router.afterEach((to,from)=>{
...
//导航已经结束,因此没有next
})
路由映射关系上的 钩子
beforeEnter
and afterEnter
const router = new VueRouter({
routes:[
{ name:home,
path:'/home',
component:Home,
beforeEnter:(to,from, next) =>{
...
},
afterEnter:(to, from)=>{
...
}
}
]
})
基本上和全局路由钩子的用法一样
组件内的钩子
beforeRouterEnter
and beforeRouterUpdate
(2.2 add) and beforeRouterLeave
export default{
data(){
return {
...
}
},
beforeRouterEnter (to, from, next){
//由于在使用这之前,导航还未确认,实例还没有被创建,所以这里面是不能调用this的
},
beforeRouterUpdate(to,from,next){
//次函数的触发规则是,在类似 /home/:id 这样的动态路由中,由于id的变化,但是组件仍然不变的情况下,便可以使用
//此时实例已经创建完成,因此,this可以登上舞台
},
beforeRouterLeave(to,from,next){
//导航离开组件对应路由会触发这个函数
//可以访问this
}
}