vue-router
安装
可使用vue add router
进行安装
或者通过 npm / yarn 方式进行安装。
使用
项目src
目录下创建 router
文件夹,在文件夹中创建index.js
在index.js 中引入并设置对应的路由:
// 引入Vue
import Vue from 'vue'
// 引入vueRouter
import VueRouter from 'vue-router'
// 引入home 组件
import HomeView from '../views/HomeView.vue'
// 模块化机制编程,需要导入Vue和VueRouter,要调用 Vue.use(VueRouter)
Vue.use(VueRouter)
// 这里是路由集合
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]
// new VueRouter 并把生成的router导出
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
// Router 构建选项:
// routes 数组类型,路由的集合
// mode 字符串类型,路由的模式,可选 "hash" (浏览器环境) | history | "abstract" (Node.js 环境)
export default router
vueRouter 构建选项:
- routes: 路由的集合
- mode: 路由模式 可选 “hash” (浏览器环境) | history | “abstract” (Node.js 环境)
- base: 应用的基路径。例如,如果整个单页应用服务在 /app/ 下,然后 base 就应该设为 “/app/”,如果是在根目录下,则应设为’/’
router-link
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
router-view
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
动态路由匹配
将某种匹配模式的的所有路由,全部映射到某一个组件
例如:/goodDetail/1
、/goodDetail/2
、/goodDetail/3
都会匹配。
当匹配到一个路由时,参数值会被设置到this.$route.params
中
{
path:'/goodDetail/:id',
name: 'GoodsDetail',
component: () => import("@/views/GoodsDetail")
}
可以匹配多个路径参数,对应的参数也会设置到 this.$route.params
中
{
path:'/goodDetail/:id/info/:tag',
name: 'GoodsDetail',
component: () => import("@/views/GoodsDetail")
}
动态路由 | 匹配路径 | $route.params |
---|---|---|
/goodDetail/:id | /goodDetail/1 | { id: 1 } |
/goodDetail/:id/info/:tag | /goodDetail/1/info/base | { id: 1, info: ‘base’ } |
注意:在这种模式下,路由从
/goodsDetail/1
跳转到/goodDetail/2
页面的生命周期不会执行,原因是组件是被复用了,此时需要通过监听$route
对象去捕获路由的变化。
通配符
{
// 会匹配所有路径
path: '*'
}
{
// 会匹配以 `/user-` 开头的任意路径
path: '/user-*'
}
当使用一个通配符时,$route.params
内会自动添加一个名为 pathMatch
参数。它包含了 URL
通过通配符被匹配的部分:
// 给出一个路由 { path: '/user-*' }
this.$router.push('/user-admin')
this.$route.params.pathMatch // 'admin'
// 给出一个路由 { path: '*' }
this.$router.push('/non-existing')
this.$route.params.pathMatch // '/non-existing'
嵌套路由
const router = new VueRouter({
routes: [
{
path: '/user/:id',
component: User,
children: [
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 <router-view> 中
path: 'profile',
component: UserProfile
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 会被渲染在 User 的 <router-view> 中
path: 'posts',
component: UserPosts
}
]
}
]
})
导航守卫
导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
参数或查询的改变并不会触发进入/离开的导航守卫, 可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。
全局前置守卫(router.beforeEach)
确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错。
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
// to 要进入的路由
// from 当前路由
// next() 继续当前路由
// next(false) 中断当前路由
// next({path:'/'}) next('/') 跳转到其他路由
// next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
})
全局解析守卫(router.beforeResolve)
注册一个全局守卫。这和
router.beforeEach
类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用
全局后置钩子(router.afterEach)
router.afterEach((to, from) => {
// ...
})
路由独享的守卫
路由配置上直接定义 beforeEnter 守卫
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
组件内的守卫
可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnter
不!能!获取组件实例this
beforeRouteUpdate
可以访问组件实例this
beforeRouteLeave
可以访问组件实例this
const Foo = {
template: `...`,
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用 beforeRouteLeave 守卫。
- 调用全局的 beforeEach 守卫。
- 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
- 在路由配置里调用 beforeEnter。
- 解析异步路由组件。
- 在被激活的组件里调用 beforeRouteEnter。
- 调用全局的 beforeResolve 守卫 (2.5+)。
- 导航被确认。
- 调用全局的 afterEach 钩子。
- 触发 DOM 更新。
- 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
路由元信息(meta)
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: { requiresAuth: true }
}
]
}
]
})
meta 中的信息会保存在 to.matched
中,是一个数组。
路由懒加载
/* webpackChunkName: "group-foo" */ 表示将路由按组分类,标记后会将 webpackChunkName 相同的路由打包到同一个包中
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')