Vue Router 基础入门
1. Vue Router
Vue Router 是依赖于 vue.js 的。所以使用前必须先引入 vue.js 文件。
vue router 是用来进行页面间跳转的连接,就像a标签。
页面中变更url,就访问到 router 中地址相对应的组件。
还有个就是路由编程式导航 this.$router.push(url地址) 也可以来进行组件间跳转。
2、Vue Router 的基础使用
html部分
- 引入js文件
<script src="./vue.js"></script>
<script src="./vue-router.js"></script>
- 指定导航连接,
<!-- router-link会被渲染成一个a标签 to属性渲染的a标签中的href属性 -->
<router-link to="/user"></router-link>
- 设置路由出口。路由匹配到的组件会被渲染到这里
<router-view></router-view>
js部分
- 创建路由组件。
const Foo = { template: `<div>foo</div>` }
const Bar = { template: `<div>bar</div>` }
- 定义路由。每个路由应该映射一个组件,其中 component 可以是通过 Vue.extend() 创建的组件构造器。
const routes = {
{path: '/foo', component: Foo},
{path: '/bar', component: Bar }
}
- 创建 router 实例,配置 routes 路由参数
const router = new VueRouter({
// 相当于 routes: routs
routes
})
- 将路由挂载到Vue实例中
new Vue({
el: '#app',
// 当对象的键与值名称相同时,可以缩写
router
})
// 在官方文档中的写法 其中el和$mount 在使用上是没有任何区别的
// 都是为了将实例化后的Vue 挂载到指定的dom元素中
const app = new Vue({
router
}).$mount('#app')
补充:路由重定向。比如我们访问 url 是 / 时,会重定向到主页,如 /home。
通过配置routes为页面设置默认展示的组件,在路由规则中添加一条规则即可。
const router = new VueRouter({
routes: [
{path: '/',rediect:'foo'},
{path: '/foo', component: Foo},
]
})
3、动态路由匹配
我们经常需要把某个模式的所有路径,全局映射到同个组件。比如我们有个 uesr 组件根据不同的 id 来渲染展示不同的页面。
这样不同的路径来用同一个组件渲染,就需要用到动态路由匹配了。使用方式:在一个路径参数使用:标记。动态的参数会被
this.$route.params获取到。
const User = {
template: `<div>{{$route.params.id}}</div>`
}
const router = new VueRouter({
routes: [
// 动态路径参数,已冒号开头。像下面的:id
{ path: '/user/:id', component: User }
]
})
输入的路径是 /user/123,$route.params 获取到的就是 {id: '123'}。
也可以进行多个参数的传递。
模式: /user/:username/post/:post_id
匹配路径: /user/even/post/123
$route.params: {username: 'even',post_id: '123'}
3.1 响应路由参数的变化
当在动态路由间进行跳转,比如从/user/123到/user/444,原理的组件实例会被复用,但是组件是声明周期钩子不会被调用。
可以使用 watch 来监测 $route 对象的变化。
const user = {
template: `<div>{{$route.params}}</div>`,
watch: {
$route(to,from) {
// to 表示的是新路径的参数
// from 表示跳转前路径的参数
}
},
}
或者使用2.2 中引入的 beforeRouteUpdate
const Bar = {
template: `<div>{{$route.params}}</div>`,
beforeRouteUpdate(to, from, next) {
// to form 和watch相同
next()
}
}
3.2 捕获所以路由或 404 Not Found 路由
使用通配符*来捕获所以路由,应该是写在路由的最后面,通长用于客户端 404 错误。$route.params.pathMatch包含被通配符匹配的路径。
// 匹配所有路由
{ path: '*' }
// 匹配已 /user-开头的任意路径
{ path: '/user-*' }
匹配优先级 一个 /user 的路径,能被 /user 路由和通配符路由匹配到。此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。
4、嵌套路由
我们想访问一个组件中的组件,比如访问user组件(父组件)中的poc(子组件)组件,就需要嵌套路由了。
子组件的出口被写在父组件中。使用 children配置嵌套路由。
// 父组件
const User = {
template: `<div>{{$route.params}}
<router-view></router-view>
</div>`,
}
// 子组件
const poc = {
template: `<div>123</div>`
}
在 VueRouter 中配置嵌套路由。是可以进行多层嵌套的。
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,children:[
{path: 'poc', component: poc},
// 空的子路由
{path: '',component: poc1 }
] },
]
})
要注意,以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。
当你访问 /user/foo 时(不带子路由路径),子路由不会显示。如果你想显示子路由,可以写个空的。
5、编程式导航
我们进行组件间的跳转,可以借助于编程式导航。
router.push(location, onComplete?, onAbort?)
location 如果提供了 path,params 会被忽略,解决办法:{path: register/${id}}。
onComplete 和 onAbort 两个回调用于导航成功完成(在所有的异步钩子被解析之后)或终止(导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由)的时候进行相应的调用。
注意:在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push。
使用router-push方法,这个方法会向 history 栈添加一个新的记录。当用户点击浏览器后退按钮时,则回到之前的 url。
这个方法的参数可以时一个字符串路径,或者一个描述地址的对象,例如
// 字符串
router.push('home')
// 对象
router.push({path: 'home'})
// 命名路由 /user/123 如果提供了path,params会被忽略
router.push({name: 'user', params: {userId: '123'}})
// 带查询参数 变成 /register?plan=private query 的值会有键值对的形式拼接到
router.push({path:'register',query:{plan: 'private'}})
就像在响应路由参数的变化中说的,如果目的地和当前路由相同,只有参数发生了变化(比如从 /user/1 到 /user/2 )。可以用watch和beforeRouterUpdate莱响应这个变化。
router.replace和router.push类型,唯一的不同就是不想 history不是添加新记录而是替换记录。
router.replace(location, onComplete?, onAbort?)
router.go(n)
//前进一步
router.go(1)
//后退一步
router.go(-1)
// 刷新当前页面
router.go()
6、命名路由
命名路由是意思就是为routes规则添加一个别名,可以使用别名进行跳转。以下我会将name设置为无意义的 aaa。
var router = new VueRouter({
routes: [
// 通过 name 属性为路由添加一个别名
{ path: '/user/:id', component: User,name: 'aaa' }
]
})
使用声明式跳转
<router-link :to="{ name: 'aaa',params: {id:123}}">User</router-link>
使用编程式导航,两种方式都会把路由导航到 /user/123 路径
router.push({name:'aaa',params:{id:123}})
7、命名视图
在页面上展示多个视图,比如像后台界面的 header头部、sidebar侧导航和main主内容的这样三个视图。
可以设置多个单独命名的视图,而不是一个出口。
<!-- 不署名,就默认为default -->
<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>
如果主页展示多个视图,可以components(有个s)赋多个组件
const router = new VueRouter({
routes: [
{path:'/',components: {
default: Foo,
a:Bar,
b:Foz
}}
]
})
7.1 嵌套路由组件
用来创建嵌套视图的复杂布局创建嵌套视图的复杂布局,可以自己写代码试试布局。
推荐看文档嵌套命名视图
8、重定向和别名
8.1 重定向
我们希望输入 / 能访问到主页,但主页的路径是 /home ,就要用到重定向了。
const router = new Router({
router: [
// redirect 来配置重定向
{path: '/',redirect: '/home'},
]
})
重定向的目标可以是一个命名的路由
const router = new VueRouter({
router: [
// foo 是别名
{path:'/',redirect:{name:'foo'}}
]
})
重定向的目标是一个方法,动态返回重定向目标
const router = new VueRouter({
routes: [
{path: '/',redicrect: to=> {
// 方法接收 目标路由作为参数
// return 重定向的字符串/路径对象
}}
]
})
8.2 别名
/a的别名是/b,意味着,当用户访问/b,URL会保持为/b,但是路由匹配的则是/a,就行用户访问/a一样
别名可以让你自由将组件映射到任意的URL,而不是受限于配置的嵌套路由结构。
别名和上面的命名路由是不同的,上面的是变量。而别名写在的是url中。配置为:
const router = new VueRouter({
routes: [
{path:'/a',component: A, alias: '/b'}
]
})
9、路由组件传参
使用如果使用$route.params.id来获取路径传参的数据不够灵活。推荐使用 props来获取参数。
布尔模式
const User = {
props: ['id'],
template: `<div>User{{id}}</div>`
}
const router = new VueRouter({
routes: [
// 如果 props 被设置为 true,router.params 将会被设置为组件属性
{ path:'/user/:id',component: User, props: true }
// 对应包含命名视图的路由,你必须分别为每个命名视图添加 props 属性
{
path: '/user/:id',
components: {default: User, sidebar: Sidebar},
props: {default: true,sidebar: false} }
]
})
对象模式
如果props是一个对象,它会被按原样设置为组件属性,当props是静态的的时候有用。
const router = new VueRouter({
routes: [
{ path:'/promotion/from-newsletter', component: Promotion, props: {newsletterPopup: false} }
]
})
函数模式
你可以创建一个函数返回props。这样你可以将参数转换为另外一种类型,将静态值于基于路由的值结合等待。
const router = new VueRouter({
routes: [
{ path:'/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
]
})
URL /search?q=vue 会将 {query: 'vue'} 作为属性值传递给searchUser组件。
请尽可能保持 props 函数为无状态,因为它只会在路由发生变化时起作用。如果你需要状态来定义 props,请使用包装组件,这样 Vue 才可以对状态变化做出反应。

浙公网安备 33010602011771号