功能
vue-router实现vue的单页面应用,vue的官方路由器,与vue核心深度集成,使vue构建单页面程序变得轻而易举
嵌套路由/视图映射
模块化,基于组件的路由器配置
路由参数,查询,通配符
查看由vue过渡系统提供动力的过渡效果
细粒度的导航控制
与自动活动css类的链接
HTML5历史纪录模式或哈希模式,在IE9中具有自动备用
可自定义的滚动行为
路由原理
与传统开发方式的区别
1 传统的开发方式,url改变后,立刻发生请求响应整个页面,有可能资源过多,可能出现白屏
2 SPA 单页面应用 主要的作用
锚点值改变后 不会立刻发送请求,而是在某个合适的时机,发送ajax请求局部改变页面的数据
优点:页面布不立刻跳转 用户体验好
模拟vue-router
<a href='#/login'> 登陆</a> var app=document.getElementById('app'); window.onhashchange=function(){ console.log(location.hash); switch(location.hash){ case '#/login': app.innerHTML='<H2>THIS IS LOGIN PAGE</H2>'; break; } }
使用vue-router
vue-router必须配vue使用
让vue使用vue-router
vue.use(Router);//vue是局部作用域需要,全局的时候不需要
挂载vue-router
Vue.component({ template:'<h2>login page</h2>' }); new Router({ mode:'', routes:[ { path:'/login', component:Login } ] });
router-link to对应route中的path
router-link 默认渲染成a标签 to属性渲染成href属性
<router-view>路由组件的出口
使用vue-router 抛出了两个全局组件 router-link router-view
抛出了两个对象 $router $route(路由信息对象)挂载到了Vue实例化对象
路由参数与动态路由
路由参数
如果各个子页面dom结构不同
动态路由
我们需要将具有给定模式的路由映射到同一个组件,也就是页面dom结构相同就可以使用动态路由,组件切换期间不会重新调用生命周期钩子,
如果需要对参数变化做出反应可以这样做:
观察route对象:watch $route;或者使用导航卫士:beforeRouteUpdate
导航守卫
需要登陆的页面设置meta为true
routes=[{ path:'/home', component:home },{ path:'/Blog', meta:{auth:true}, component:Blog }];
router.beforeEach 在进入路由之前
next()中参数对象与route中的对象一致
路由导航
声明式导航
直接在页面通过router-link创建声明式导航的锚标记
编程式导航 router.push(location,onComplete?,onAbort?)
使用路由器的实例
this.$router.push({path:'/login'})
参数可以是字符串路径,也可以是位置描述符对象
单击<router-link :to="..."></router-link>等效于调用router.push(...)=====>window.history.pushState
参数 query 和params
query
参数直接使用?拼接在路径的后面
router.push({ path: 'register', query: { plan: 'private' } })===>/register?plan=private
params
params与query不同:
const userId=123; //参数直接拼接在路径的后面需要使用name属性 router.push({ name: 'user', params: { userId } });====>/user/123 //使用path属性,路径不会变,刷新页面之后参数丢失 router.push({ path'/user', params: { userId } });===》/user
tips: vue实现组件式开发,我们要做的就是让组件映射到路由,并让vue-router知道在哪里渲染它们。
匹配任何内容,使用*,通常用于404客户端
匹配优先级
同一个URL可能会被多个路由匹配,匹配优先级由路由定义的顺序确定:定义路由越早,优先级越高
router.replace(location,onComplete?,onAbort?)
与router.push一样,区别,没有推进新的历史纪录条目,它替换了当前的条目
<router-link :to="..." replace></router-link> router.replace======》window.history.replaceState
router.go(n)
参数是一个整数,指示在历史记录堆栈中前进或后退多少步,类似于window.history.go(n)
命名视图
有时需要同时显示多个视图而不是嵌套它们,这时命名视图排上用场。
<router-view class="view one"></router-view> <router-view class="view two" name="a"></router-view> <router-view class="view three" name="b"></router-view>
不带名称的视图默认是default;一个视图使用组件渲染,多个视图需要多个组件,确保使用components(带有s)选项:
const router=new VueRouter({ routes:[ path:'/', components:{ default:Foo, a:Bar, b;Baz } ] });
重定向和别名
导航卫士不应用于重定向的路线
导航卫士
参数和查询更改不会触发输入/离开导航卫士,您可以观察$route对象对这些更改做出反应,也可以使用beforeRouteUpdate组件内防护。
router.beforeEach(to,from,next)
router.beforeResolve
router.afterEach
在路由的配置对象上定义防护:beforeEnter
组件内防护:
beforeRouteEnter 不能访问this 组件还没有创建,next支持回调,在回调函数中可以访问this
beforeRouteUpdate 可以直接访问this,next不支持回调
beforeRouteLeave 可以直接访问this,next不支持回调
该beforeRouteLeave通常是用来防止用户意外离开未保存修改的路线。可以通过调用取消导航next(false)
。
beforeRouteLeave (to, from, next) { const answer = window.confirm('Do you really want to leave? you have unsaved changes!') if (answer) { next() } else { next(false) } }
完整的导航分辨率流程
1 导航已触发
2 beforeRouteLeave
3 beforeEach
4 beforeRouteUpdate
5 beforeEnter
6 解决异步路由组件
7 调用已beforeRouteEnter激活的组件
8 beforeResolve
9 导航已确认
10 全局 afterEach
11触发DOM更新
12 next
meta元字段用于权限控制
给未来路由做权限控制 全局路由守卫 来做参照条件;routes配置中的每个路由对象都成为路由记录。路由记录可以嵌套。因此,当路由匹配时,它可能会匹配
多个路由记录。通过$route.matched 获取Array,需要迭代检查路由记录中的meta字段。
在全局导航中判断权限:
router.beforeEach(function(to,from,next){ if(to.mata.auth){//如果需要登陆 //判断是否登陆 if(localStorage.user){//已登陆 next();//直接放行 }else{ next({path:'/login'});//编程式导航 } } })
transitions
由于<router-view>实质上时动态组件,因此我们可以使用<transition>组件以相同的方式对其应用过渡效果:
<transition> <router-view></router-view> </transition>
滚动行为
当使用客户端路由时,我们可能希望在导航到新路由时滚动到顶部,或者像重新加载真是页面一样保留历史记录条目的滚动位置。vue-router可以完全自定义路线导航中的滚动行为。
创建路由实例时,可以提供以下scrollBehavior功能:
const router=new VueRouter({ routes:[....], scrollBehavior(to,from,savedPosition){ } });
savedPosition仅在通过popstate导航(由浏览器的后退/前进按钮触发)时才可用。该函数可以安徽滚动位置对象:
{x:number,y:number}
{selector:string,offset?:{x:number,y:number}}
如果返回错误值或空对象,则不会滚动
demo:
scrollBehavior (to, from, savedPosition) { return { x: 0, y: 0 } }
使页面滚动到所有路线导航的顶部。
路由懒加载
将Vue的异步组件功能和webpack的代码拆分功能结合在一起,可以实现路由懒加载
首先可以将异步组件定义为返回Promise的工厂函数
const Foo=()=>Promise.resolve()
其次,在webpack2.0中使用 动态导入 语法来指示代码分割点:
import('../Foo.vue') //return a Promise
两者结合,就可以定义一个异步组件该组件将由webpack自动代码拆分:
const Foo=import('../Foo.vue')