Vue Router基础
Vue Router基本使用
-
HTML中的使用
- 使用
router-link组件在 HTML 中进行导航 - 通过传入
to属性指定链接 <router-link>默认会被渲染成一个<a>标签
- 使用
-
JavaScript中的使用注意点
在注入路由器之后,可以在任何组件内通过
this.$router访问路由器,通过this.$route访问当前路由当
<router-link>对应的路由匹配成功时,将自动设置class属性值.router-link-active
动态路由匹配
vue-router 的路由路径中可以使用“动态路径参数”
动态路径参数使用冒号 : 标记,如 path: '/user/:id',当匹配到一个路由时,参数值会被设置为 this.$route.params,可以在对应的每个组件内使用
-
响应路由参数的变化
在使用路由参数时,原来的组件实例会被复用,同时,组件的生命周期钩子不会再被调用
在复用组件时,如果想对路由参数的变化作出反应,可以通过使用
watch监测$route对象,或者使用beforeRouteUpdate导航守卫 -
捕获所有路由或 404 Not found 路由
如果想匹配任意路径,可以使用通配符
*,{ path: '*' }一般来说,含有通配符的路由应该放在最后,它通常用于客户端 404 错误
当使用了一个通配符时,
$route.params内会自动添加一个名为pathMatch参数,它包含了 URL 通过通配符被匹配的部分通配符在 path 中可以组合使用,如
{ path: '/user-* ' } -
高级匹配模式
vue-router使用 path-to-regexp 作为路径匹配引擎,支持多种高级的匹配模式 -
匹配优先级
同一个路径可以匹配多个路由,匹配的优先级会按照路由的定义顺序,路由定义得越早,优先级越高
嵌套路由
vue-router 可以进行路由的嵌套, <router-view> 是最顶层的出口,渲染最高级路由匹配到的组件,被渲染的组件也可以包含自己的嵌套 <router-view>
VueRouter 的参数中使用 children 配置,children 匹配的组件会被渲染在定义它的 <router-view> 中
注意: 以 / 开头的嵌套路径会被当作根路径,换而言之,在 children 中的子路由的路径不需要再以 / 开头
编程式的导航(编程式路由导航)
-
router.push(location, onComplete?, onAbort?)
注意: 在 Vue 实例内部,可以通过
$router来访问路由实例,因此可以调用this.$router.pushrouter.push方法可以导航到不同的 URL,这个方法会向 history 栈中添加一个新的记录,router.push方法的参数 可以是一个字符串路径,或者一个描述地址的对象// 字符串 router.push('home') //对象 router.push({ path: 'home' }) // 命名路由 router.push({ name: 'user', params: { userId: '123' }}) // 携带查询参数 router.push({ path: 'register', query: { plan: 'private' }})注意: 如果提供了
path,params会被忽略,携带 params 有两种写法:// 第一种:使用命名路由 router.push( { name: 'user', params: { userId: '123' }}) // 第二种:使用 path,需要用模板字符串将 params 的数据拼接到 url后面 router.push( {path: `/home/${userId}`})onComplete和onAbort回调可以作为第二个和第三个参数传入onComplete回调函数会在导航成功完成(所有的异步钩子被解析之后)调用onAbort回调函数会在终止(导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由)时调用注意: 如果目的地和当前路由相同,只有路由参数发生了改变,需要使用
beforeRouteUpdate来响应这个变化 -
router.replace(location, onComplete?, onAbort?)
跟
router.push的功能类似,唯一的不同是,router.replace不会向 history 添加新纪录,而是替换当前的 history 记录 -
router.go(n)
router.go方法的参数是一个整数,表示在 history 记录中向前或者后退多少步
命名路由
在创建 Router 实例的时候,可以在 routes 配置中通过 name 属性来给某个路由设置名称
在 router-link 的 to 属性传一个对象,示例如下:
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
命名视图
如果需要在一个布局上渲染多个视图(即渲染多个组件),可以使用命名视图,在 <router-view> 中指定 name 与 components 中的组件进行匹配
如果 router-view 没有设置名字,则默认为 default
一个视图用一个组件渲染,因此多个视图需要多个组件进行渲染。componenets 配置示例如下:
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: component1
name: component2
}
}
]
})
重定向和别名
-
重定向
重定向通过
routes配置来完成,重定向的目标可以是路径、命名路由、动态返回重定向目标的方法,示例如下:const router = new VueRouter({ routes: [ // 路径 { path: '/a', redirect: '/b'} // 命名路由 { path: '/a', redirect: { name: 'abc' }} // 方法接收 目标路由 作为参数,return 重定向的 字符串路径/路径对象 { path: '/a', redirect: to => { return 字符串路径/路径对象 }} ] }) -
别名
别名的用处在于比如
/a的别名是/b,则当用户访问/b时, URL 会保持为/b,但是路由匹配则为/a,示例如下:const router = new VueRouter({ routes: [ { path: '/a', componenet: A, alias: '/b' } ] })别名的功能在于可以自由地将 UI 结构映射到任意的 URL,即可以控制 URL 跳转渲染的组件,让一个 UI 结构能够被多条 URL 地址所访问到
别名在指定多个路径时,
alias后面可以采用数组的写法
路由组件传参
在组件上使用 $route 会使组件与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,对组件的复用性有很大的影响,可以通过 props 将组件和路由解耦,示例如下:
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true },
// 路由如果包含命名视图,则需要对每个命名视图添加 `props`
{
path: '/user/:id',
component: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
})
-
布尔模式
如果
props被设置为true,route.params将会被设置为组件属性,组件中可以通过props来接收 -
对象模式
如果
props是一个对象,它会被按原样设置为组件属性,组件中使用props来接收对应的数据,当routes中的props是静态的时候有用 -
函数模式
如果创建一个函数返回
props,可以将参数转换成另一个类型,将静态值与基于路由的值结合等,示例如下const router = new VueRouter({ routes: [ { path: '/search', componenet: SearchUser, props: route => ({ query: route.query.q }) } ] })
HTML5 History 模式
vue-router 默认 hash 模式——使用 URL 的 hash 来模拟一个完整的 URL,当 URL 改变时,页面不会重新加载,hash 模式会让 url 中存在 /#,不够美观
可以使用路由的 history 模式 ,这个模式充分利用了 history.pushState API 来完成 URL 跳转而无须重新加载页面,可以通过将 mode 属性设置为 history 来进行设定
这个模式存在的问题是需要有后台配置支持,因为应用是单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接输入地址访问时,会返回 404,需要在服务端增加一个覆盖所有情况的候选资源,如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html页面