官方文档地址:https://router.vuejs.org/zh/
vue-router 是 Vue.js 官方的路由管理器。它和Vue.js深度集成,让构建单页面应用变得易如反掌。
1,这是一个简单的栗子
HTML:
<script src="http://unpkg.com/vue/dist/vue.js"></script>
<script src="http://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<h1>hello app</h1>
<p>
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个`<a>`标签. -->
<router-link to="/foo">go to Foo</router-link>
<router-link to="/bar">go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 匹配到的组件会被渲染在这里 -->
<router-view></router-view>
</div>
JavaScript:
// 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
// 1.定义路由组件。
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 2.定义路由
// 每个路由应该映射一个组件。其中“component” 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者只是一个组件配置对象。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 3.创建router实例,然后传入 routes 配置 和 其他别的配置参数
const router = new VueRouter({
routes // 缩写,相当于 routes: routes
})
// 4.创建和挂在跟实例。
// 记得要通过 router 配置参数注入路由,从而让整个应用都有路由功能
const app = new Vue({
router
}).$mount('#app')
通过注入路由器,可以在任何组件内通过 this.$router
访问路由器,也可以使用 this.$route
访问当前路由。
2,动态路由匹配
当需要把某种模式匹配到的所有路由,全部映射到同一个组件上。例如,我们有一个User组件,对于ID各不相同的用户,都要使用这个组件来渲染,在路由路径中使用动态路由参数
实现该效果
const User = {
template: '<div>User</div>'
}
const router = new VueRouter({
routes: [
// 动态路由参数,以冒号开头
{ path: '/user/:id', component: User }
]
})
这时,像 /user/id1
、/user/id2
都会映射到同一组件
使用 this.$route.params.id
获取 参数的值
注
:当路由参数发生变化时,例如从/user/id1
跳转到/user/id2
,原来的组件实例会被复用
,因为两个路由都渲染同个组件,比起销毁再创建,复用会显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用
。
解决方案
:
1,使用 watch (监听变化)$route
对象
const User = {
template: '...',
watch: {
'$route' (to, from) {
// 对路由变化做出相应
}
}
}
2,使用 2.2 中引入的 beforeRouteUpdate
守卫
const User = {
template: '...',
beforeRouteUpdate(to, from, next) {
// react to route change ...
// don't forget to call next()
}
}
3,嵌套路由
父组件中需要 <router-view>
组件
父组件的路由对象中,需要有【children】属性,当子组件的path为空时,代表父组件匹配成功时, <router-view>
中需要渲染的组件。
先来个栗子
User组件
const User = {
template: `
<div id="user">
<h2>{{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`
}
路由
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
// 当/user/:id 匹配成功,
// userHome 会被渲染在 User的 <router-view>中
{ path: '', component: UserHome },
{
// 当 /user/:id/profile渲染成功,
// UserProfile 会被渲染再User的<router-view>中
path: 'profile',
component: 'UserProfile'
},
{
// 当 /user/:id/posts渲染成功,
// UserPosts 会被渲染再User的<router-view>中
path: 'posts',
component: 'UserPosts'
}
]
}
]
})
4,编程式导航
(1)router.push
会向 history栈中添加一个新纪录,当用户点击浏览器后退按钮时,会回到之前的URL,类似于 window.history.pushState
<router-link :to=""></router-link>
栗子:
const userId = 123
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 当 path 和 params同时存在时 params不生效
router.push({ path: '/user', params: { userId }}) // -> /user
(2)router.replace
不会向 history 栈中添加新记录,会替换掉当前的history 记录(用法同上),类似于window.history.replaceState
<router-link :to='...' replace>
(3)router.go(n)
表示在history记录中,向前或者向后退多少步,类似window.history.go(n)
栗子
// 在浏览器中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 如果 history 记录不够用,那就默默地失败呗
router.go(100)
router.go(-100)
5,命名路由
来个栗子
const router = new VueRouter({
routes: [
path: '/user/:userId',
name: 'user', // 对路由进行命名
component: User
]
})
声明式路由跳转写法
<router-link :to="{ name: 'user', params: { userId: 123 } }"></router-link>
编程式路由跳转写法
router.push({ name: 'user', params: { userId: 123 } })
6,命名视图
当需要创建一个布局,有 sidebar(侧导航)和main(主内容)两个试图时,就可以使用命名试图
<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)配置【router-view】的name值和需要显示的组件绑定,如果没有name属性,默认使用【default】
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})