vue router
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
使用vue-router
安装模块
npm install vue-router
示例
import Vue from 'vue'
import VueRouter from "vue-router"
Vue.use(VueRouter)
import 'Home' form './view/Home'
import 'Channel' form './view/Channel'
// 创建路由实例对象
let router = new VueRouter({
routers:[{
path:'/',
name:'Home',
alias:'/index', // 别名
component:Home
},{
path: '/(coming_soon|in_theaters|top250)',// 合法的正则都可以;
component: Channel
}]
})
export default router
注入vue
import App from './App'
import router from './router'
new Vue({
el:'#app', // 渲染的挂载点;
router, // 路由配置;
template:'<App />' //使用组件;
component:{
App //注入组件
}
})
this.$router router实例对象,每个组件都可以拿到;vue实例注入的router
this.$route 当前激活的路由信息对象,每个组件实例都会有
告知路由渲染位置: App组件
<router-view></router-view>
hash或者history模式路由
默认hash模式
hash
使用URL的hash来模拟一个完整的URL,于是当URL改变时,页面不会重新加载。 mode:'history'
history
需要支持H5的history api
这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。
还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 oursite.com/user/id 就会返回404。
所以呢,在服务端增加一个覆盖所有情况的候选资源:如果URL匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
router-link组件
<router-link></router-link>
跳转地址,不用再切换mode模式时候手动修改进行模式匹配; 前进后退; 点击时默认添加class,可设置; 在router-link组件上设置的class会映射在响应组件的根节点上;
props
to
跳转地址
to="/home"
:to="home"
:to="{path:'/home', params: { user: 1 }}" // route.params读取
:to="{path:'/home', query: { user: 1 }}" // 查询字符串传参,route.query读取
tag
默认a标签,修改生成标签;
生成a以外的标签不会添加href,默认会添加事件监听来进行url改变;
如果需要查看路径可以在router-link内部再嵌套a标签,此时router-link的to属性会自动渲染到a标签的href属性上;
active-class
默认router-link-active; 路由构造函数选项linkActiveClass: "active"进行全局配置; 单独设置active="pink"优先级高于路由设置;
event
改变默认事件click 事件名
exac
布尔值(出现即可,可省略),路径精确匹配自动触发点击状态,默认是贪婪匹配
append
布尔值(出现即可,可省略),在当前路径后添加此路径
exact-active-class:2.5.0+
默认值: "router-link-exact-active" 路由构造函数选项 linkExactActiveClass 进行全局配置 单独设置router-link-exact-active="pink"优先级高于路由设置
重定向
let router = new VueRouter({
routers:[{
path:'*',
// redirect:'/'
// redirect:{ path: '/index' },
// redirect:{ name: 'Home' },
redirect: (to) => { //动态设置重定向的目标
// to:目标路由对象
// return '/home' //返回跳转路径;
// 根据不同的path、hash...可以做不同的重定向目标;
if(to.path === '/about'){
return 'home';
}else if(to.path === '/work'){
return {path:'/home'}
}else{
return {name:'Home'}
}
}
}]
})
路由嵌套
let router = new VueRouter({
routers:[{
path:'/about'
alias:'/index',
component:about,
children: [{
path:'', // 默认子路由,设置了默认子路由父路由就不要设置name属性了,否则vue会发出警告,name设置在默认子路由即可;,
name:'About',
component:'work'
},{
path:'study', // 不用加/,加了就是根路径了
name:'study',
component: study
}]
}]
})
渲染的位置也是在父级组件里,只需添加<router-view></router-view>;
在渲染子路由的时候父组件也会被渲染;
此时渲染路径是/about/study;
如果想要'/study'可以这样处理:
在router-link中to属性使用绑定对象表示:to={name:'Study'};
子路由的path中加上/,形成'/study'; 此时是组件嵌套,路由不嵌套
在渲染时候还是同样的渲染,只是路径上就没有了父级路由;
命名视图
有名字的router-view
<router-view></router-view> // 渲染默认路由
<router-view name="slider"></router-view> // 命名视图渲染
let router = new VueRouter({
routers:[
{
path:'/document',
alias:'docu',
name:'Document',
components:{
default: document,
slider: slider
}
}
]
})
滚动行为
自定义路由切换时页面如何滚动。 这个功能只在支持 history.pushState 的浏览器中可用。
let router = new VueRouter({
routes: [...],
scrollBehavior(to, from, savePosition) {
// 在点击浏览器的前进、后退、切换导航时候触发
// to:目标路由对象 去哪里
// from:离开的路由对象 哪里来
// savePosition:记录滚动条的坐标 只有在点击前进后退的时候记录值
if (to.hash) { // 有hash使用hash
return {
selector:to.hash
}
} eles { // 没有hash,检测是否有保存的滚动条坐标;
if(saverPosition){
return saverPosition;
}else{
return {x:0,y:0};
}
}
}
})
动态路径
匹配到的所有理由,都映射的同一个组件,根据不用的params进行不同的渲染;
let router = new VueRouter({
routers:[{
path:'/user/:userId?', // 正则userId? 表示userId可有1次也可以没有;
alias:'/user',
name:'User',
component:user,
}]
})
通过this.$route.params.userId读取。
路径改变了,页面信息需要重新渲染怎么办?
new Vue({
created(){
// 渲染组件只会调用一次此声明周期函数;
// 复用这个组件,此声明周期函数不会再次调用;
// 地址一旦发生变化,$route对象就会重新生成;
// 所以可以通过监听$route对象来判断路由是否改变;
// 再根据$route对象来重新渲染页面信息;
// 导航守卫也可以下面有介绍
},
watch:{
$route(){
console.log(this.$route);
}
}
})
过渡动效
提供了transition的封装组件,添加过渡动画 添加删除css类名
<transition name=”go” mode=”out-in”>
<router-view></router-view>
</transition>
name:过渡动画前缀;默认是v;
mode:过渡模式:默认同时进行;
in-out:进入的先过渡;
out-in:离开的先过渡;
路由元信息
在路由配置中meta可以配置一些数据,用在路由信息对象中访问meta中数据:$route.meta;
let router = new VueRouter({
routers:[{
path:’/’,
component:home,
meta:{
info:'来自index的元信息’
}
}]
})
编程式导航
借助 router 的实例方法,通过编写代码来实现
router.push()
| 声明式 | 编程式 |
|---|---|
<router-link :to="..."> |
router.push(...) |
router.push()会向 history 添加新记录,该方法的参数可以是一个字符串路径,或者一个描述地址的对象。
如果提供了 path,params 会被忽略,需要提供路由的 name 或手写完整的带有参数的 path:
const userId = 123
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
router.replace()
| 声明式 | 编程式 |
|---|---|
<router-link :to="..." replace> |
router.replace(...) |
跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是替换掉当前的 history 记录
router.go(n) // 在history记录中向前或者后退多少步,正数先前,负数后退
router.back() // 后退
router.forward() // 前进
router.push、router.replace 和 router.go 跟 window.history.pushState、 window.history.replaceState 和 window.history.go好像, 实际上它们确实是效仿 window.history API 的。
导航守卫
导航发生变化时,导航守卫用来拦截导航,让它完成跳转或取消
执行导航守卫位置
router实例全局
单路由
组件中
导航守卫
router实例全局
beforeEach、beforeResolve、afterEach
在 2.5.0+ 可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
router.afterEach((to, from) => {
// ...
})
单路由
beforeEnter
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
组件内的钩子
beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave;
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
// 此时next可以传入一个函数,接受一个参数,此参数就是组件的实例;
next( (vm)=>{ vm.age='23' } )
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
钩子函数接收的参数
to: 要进入导航的路由对象 到哪里去
from:要离开导航的路由对象 从哪里来
next:用来决定跳转或取消导航
next('/login') 跳转到/login
next() 正常跳转
完整的导航解析流程
1.导航被触发。
2.在失活的组件里调用离开守卫。
3.调用全局的 beforeEach 守卫。
4.在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
5.在路由配置里调用 beforeEnter。
6.解析异步路由组件。
7.在被激活的组件里调用 beforeRouteEnter。
8.调用全局的 beforeResolve 守卫 (2.5+)。
9.导航被确认。
10.调用全局的 afterEach 钩子。
11.触发 DOM 更新。
12.用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
路由对象属性
表示当前激活的路由的状态信息,每次成功的导航后都会产生一个新的对象。
route.path 类型: string 字符串,对应当前路由的路径,解析为绝对路径,如 "/foo/bar"。
route.params
类型: Object
一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。
route.query
类型: Object
一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则有 route.query.user == 1,如果没有查询参数,则是个空对象。
route.hash
类型: string
当前路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串。
route.fullPath
类型: string
完成解析后的 URL,包含查询参数和 hash 的完整路径。
route.matched 类型: Array 一个数组,包含当前路由的所有嵌套路径片段的路由记录。路由记录就是 routes 配置数组中的对象副本(还有在 children 数组)。
const router = new VueRouter({
routes: [
// 下面的对象就是 route record
{ path: '/foo', component: Foo,
children: [
// 这也是个 route record
{ path: 'bar', component: Bar }
]
}
]
})
当 URL 为 /foo/bar,$route.matched 将会是一个包含从上到下的所有对象(副本)。
route.name
当前路由的名称,如果有的话。(查看 命名路由)