使用
1安装
npm install vue-router
2新建router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//路由规则
const routes = [
{
path: './home',
component: () => import('xx/home.vue')
},
{
path: './about',
component: () => import('xx/about.vue')
}
]
//实例化路由对象
const router = new VueRouter({
routes // (缩写) 相当于 routes: routes
})
export default router
3创建和挂载根实例
在main.js:
const app = new Vue({
router,
render: h => h(App)
}).$mount('#app')
通过注入路由器,我们可以在任何组件内通过this.$router
访问路由器,也可以通过this.$route
访问当前路由。
说明:
--router:路由器对象,通过new Vue()暴露出来的实例对象,它上面有一些用来操作路由切换的方法(编程式导航的方法)通过this.$router
去使用
--route:路由对象,包含当前匹配的路由的信息,通过this.$route
去使用
// http://localhost:8080/#/topicShare?topic_id=1915
this.$route.path// "/topicShare"
this.$route.query// object, topic_id:1915
this.$route.params// object
this.$route.fullPath// "/topicShare?topic_id=1915"
this.$route.name// ""
this.$route.meta// object
this.$route.matched// array
动态路由匹配
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{
path: '/user/:id',
component: () => { 'xxx/User.vue' }
}
]
})
/user/foo 和 /user/bar 都将映射到相同的路由,通过this.$route.params.id获取当前路由id
响应路由参数的变化
当使用动态路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用,组件的生命周期钩子不会再被调用。
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象:
const User = {
template: '...',
watch: {
'$route' (to, from) {
// 对路由变化作出响应...
}
}
}
或者使用 2.2 中引入的 beforeRouteUpdate
导航守卫:
const User = {
template: '...',
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}
}
有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: () => import('xx/User.vue'),
children: [
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 <router-view> 中
path: 'profile',
component: () => import('xx/UserProfile.vue')
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 会被渲染在 User 的 <router-view> 中
path: 'posts',
component: () => import( 'xx/UserPosts.vue')
},
{
// 当 /user/:id 匹配成功,
// UserHome 会被渲染在 User 的 <router-view> 中
path: '',
component: () => import('xx/UserHome.vue')
}
]
}
]
})
编程式导航
声明式导航 | 编程式导航 |
---|---|
<router-link :to="..."> | this.$router.push(...) |
<router-link :to="..." replace> | this.$router.replace(...) |
wu | this.$routergo(1) |
// 字符串
this.$router.push('home')
// 对象
this.$router.push({ path: 'home' })
// 命名的路由
this.$router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
this.$router.push({ path: 'register', query: { plan: 'private' }})
如果提供了 path,params 会被忽略。
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
this.$router.replace()//替换掉当前的 history 记录,不会向 history 添加新记录
this.$router.go(n)//在 history 记录中向前或者后退多少步
命名路由---name
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: () => import('xx/User.vue')
}
]
})
要链接到一个命名路由,可以给 router-link 的 to 属性传一个对象:
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
这跟代码调用 router.push() 是一回事:
this.$router.push({ name: 'user', params: { userId: 123 }})
命名视图---同级展示多个视图
<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>
如果 router-view 没有设置名字,那么默认为 default
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
重定向---redirect
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
模式---mode
vue-router 默认 hash 模式,有#
const router = new VueRouter({
mode: 'history',
routes: [...]
})
路由元信息---meta
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
meta: { requiresAuth: true }
}
]
})
eg:在全局导航守卫中检查元字段
router.beforeEach((to, from, next) => {
//to:即将要跳转的路由;matched:array; array.some()检测数组中的元素是否满足指定条件
if (to.matched.some(record => record.meta.requiresAuth)) {
// this route requires auth, check if logged in
// if not, redirect to login page.
if (!auth.loggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next() // 确保一定要调用 next()
}
})
滚动行为
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滚动到哪个的位置
return { x: 0, y: 0 }
}
})
路由懒加载
const router = new VueRouter({
routes: [
{ path: '/foo', component: () => import('xx/Foo.vue') }
]
})
<router-link>的props
1to
<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 渲染结果 -->
<a href="home">Home</a>
<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}"
>Register</router-link
>
2replace
设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),于是导航后不会留下 history 记录。
<router-link :to="{ path: '/abc'}" replace></router-link>
3append
设置 append 属性后,则在当前 (相对) 路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b
<router-link :to="{ path: 'relative/path'}" append></router-link>
4tag
想要 <router-link> 渲染成某种标签,例如 <li>。 可以使用 tag prop 类指定何种标签,同样它还是会监听点击,触发导航。
<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染结果 -->
<li>foo</li>
5active-class
设置链接激活时使用的 CSS 类名
6exact
精确匹配模式
<router-view> 的Props
name命名视图
<template>
<div>
<keep-alive :exclude="keepAliveExclude">
<router-view />
</keep-alive>
</div>
</template>