介绍
学习vue-router的一些学习笔记,所有笔记内容请看 vue-router学习笔记
动态路由
需要把某种模式匹配到所有的路由,全部映射到同个组件时。我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:
const User = {
template:'<div>User</user>'
}
const router = new VueRouter({
routes:[
{
// /user/foo和/user/bar 都会映射到
// User组件中
path:'/user/:id',// 动态参数
component:User
}
]
})
现在,像 /user/foo 和 /user/bar 都将映射到相同的路由。
路径参数使用:标记,当匹配到一个路由时,路径参数值可以是使用this.$router.params获取到,可以在每个匹配到的组件中使用,如下,可以更新 User 的模板,输出当前用户的 ID:
const User = {
template:'<div>User{{$router.params.id}}</user>'
}
可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params 中。例如:
除了 $route.params 外,$route 对象还提供了其它有用的信息,例如,$route.query (如果 URL 中有查询参数)、$route.hash 等等。
响应路由参数的变化
当使用路由参数时,例如从/user/foo 跳转到 / user/bar 时,变化的只是参数 foo ->bar,此时组件没有改变,还是使用的原来的组件,原来的组件实例会被复用。因为两个路由都使用同一个组件,比起销毁再创建,复用则显得更加高效。
当复用时,组件的生命周期钩子函数不会再执行。
注意是:
(1)从同一个组件跳转到同一个组件。
(2)生命周期钩子created和mounted都不会调用。
复用组件时,如果想重新执行生命周期函数,可以对$route使用wath函数进行监听:
如下对user 模块进行更改:
const User{
template: '...',
watch:{
'$route'(to,from){
// 重新执行生命周期函数
}
}
}
具体示例如下所示:
created () {
console.log(this.getStatus(this.$route.path))
this.userpath() //我要执行的函数
},
methods: {
getStatus (urlStr) {
var urlStrArr = urlStr.split('/')
return urlStrArr[urlStrArr.length - 1]
}
},
// 使用watch函数监听$route的变化,当发生变化时,再次调用需要执行的
// 函数
watch: {
'$route' (to, from) {
console.log(this.getStatus(this.$route.path))
this.userpath() //再次调起我要执行的函数
}
}
或者使用导航守卫:
const User = {
template: '...',
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}
}
捕获所有路由或者 404 not found 路由
常规参数只会匹配被 / 分割的URL片段中的字符,如果想要匹配任意路径,使用通配符 *
如下所示:
{
// 匹配任意路径
path:'*',
component:..
}
{
// 匹配以'/user-'开头的任意路径
path:'/user-*',
componenet:..
}
注意:
使用通配符,要注意路由顺序,含有通配符的路由放在最后。路由{path : ‘ * ’},通常用于客户端404错误。
当使用通配符时,$route.params 内会自动添加一个名为 pathMatch 参数,表示url中被通配符匹配到的部分。
如下所示:
// 给出一个路由{path: '/user-*'}
this.$route.push('/user-admin')
this.$route.params.pathMatch // pathMath匹配部分为admin
// 给出路由{ path : '*'}
this.$route.push('/non-existing')
this.$route.params.pathMatch // 匹配 '/non-existing'
高级匹配模式
vue-router 使用 path-to-regexp 作为路径匹配引擎,所以支持很多高级的匹配模式
路由匹配优先级
有时,一个路径可以匹配多个路由,此时,匹配的优先级按照路由定义的顺序,谁先定义,就先匹配谁。
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// The matching uses path-to-regexp, which is the matching engine used
// by express as well, so the same matching rules apply.
// For detailed rules, see https://github.com/pillarjs/path-to-regexp
const router = new VueRouter({
mode: 'history',
base: __dirname,
routes: [
{ path: '/' },
// params are denoted with a colon ":"
{ path: '/params/:foo/:bar' },
// a param can be made optional by adding "?"
{ path: '/optional-params/:foo?' },
// a param can be followed by a regex pattern in parens
// this route will only be matched if :id is all numbers
{ path: '/params-with-regex/:id(\\d+)' },
// asterisk can match anything
{ path: '/asterisk/*' },
// make part of the path optional by wrapping with parens and add "?"
{ path: '/optional-group/(foo/)?bar' }
]
})
new Vue({
router,
template: `
<div id="app">
<h1>Route Matching</h1>
<ul>
<li><router-link to="/">/</router-link></li>
<li><router-link to="/params/foo/bar">/params/foo/bar</router-link></li>
<li><router-link to="/optional-params">/optional-params</router-link></li>
<li><router-link to="/optional-params/foo">/optional-params/foo</router-link></li>
<li><router-link to="/params-with-regex/123">/params-with-regex/123</router-link></li>
<li><router-link to="/params-with-regex/abc">/params-with-regex/abc</router-link></li>
<li><router-link to="/asterisk/foo">/asterisk/foo</router-link></li>
<li><router-link to="/asterisk/foo/bar">/asterisk/foo/bar</router-link></li>
<li><router-link to="/optional-group/bar">/optional-group/bar</router-link></li>
<li><router-link to="/optional-group/foo/bar">/optional-group/foo/bar</router-link></li>
</ul>
<p>Route context</p>
<pre>{{ JSON.stringify($route, null, 2) }}</pre>
</div>
`
}).$mount('#app')