本文共 6658 字,大约阅读时间需要 22 分钟。
Vue Router 是 Vue.js官方的路由管理器。是我们使用Vue构建的SPA(单页应用 Single Page Application)的路径管理器。本质上就是建立页面Url与组件之间的映射关系。
npm install vue-router -S复制代码
// 项目入口文件main.js// 1. 引入vue、vue-routerimport Vue from 'vue'import VueRouter from 'vue-router'// 2. 引入项目组件import App from './App.vue'import Home from './components/Home.vue'import Hello from './components/Hello.vue'// 3. 调用vue-routerVue.use(VueRouter)// 4. 创建router实例,定义路由配置const router = new VueRouter({ routes: [ { path: '/home', component: Home }, { path: '/hello', component: Hello }, { path: '/', // 根目录重定向至 /home redirect: '/home' } ]})// 5. 创建、挂载根实例并注入路由new Vue({ render: h => h(App), router}).$mount('#app')复制代码
App.vue
中插入导航及视图渲染标签复制代码
使用场景
某个模式下匹配到的所有路由,都映射到同一组件。例如不同用户的个人信息页面,或者不同文章页面等。
要点概括
path: '/ComponentA/:xxx'
ComponentA
中通过this.$route.params.xxx
获取参数// Main.js // 定义路由配置时路径使用动态参数(以冒号开头即可)const router = new VueRouter({ routes: [ { path: '/user/:id', component: User } ]})// User.vue// 路由匹配成功时,参数会被设置到this.$route.params中export default { ... // 组件内的路由导航守卫 beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this`,通过传回调给 next并把组件实例作为回调方法的参数来访问组件实例 next(vm => { vm.getUserInfo(vm.$route.params.id) }) }, // 组件内的路由导航守卫 beforeRouteUpdate(to, from, next) { // 在当前路由改变,但是该组件被复用时调用 this.getUserInfo(this.$route.params.id) }}// User.vue// 在模板插值语法中,通过 $route.params.id 获取路径参数复制代码用户ID:{
{$route.params.id}}用户名:{
{userInfo.name}}
使用场景
应用中组件存在多层嵌套组合的关系。
要点概括
children
字段,配置类似routes
<router-link>
及渲染出口<router-view>
标签// Main.js // 定义路由配置时路径使用children字段,配置类似routesconst router = new VueRouter({ routes: [ { path: '/user', component: User, children: [ {path: 'info', component: UserInfo}, {path: 'posts', component: UserPosts} ] } ]})// User.vue// 在模板中,插入嵌套的及 复制代码用户User组件
用户信息 用户文章
使用场景
routes
内配置或children
内配置的区别)要点概括
<router-view>
并设置name
属性components
字段代替component
字段 多个scomponents
对象内,key为<router-view>
标签的name
属性(没设置时,默认为default
),value为要渲染的组件// App.vue// 在模板中,配置多个路由渲染出口``并设置`name`属性 // Main.js // 配置路由时使用components字段代替component字段,key为命名视图
主页 标签的`name`属性(没设置时,默认为`default`),value为要渲染的组件const router = new VueRouter({ routes: [ { path: '/', components: { default: Index, view1: View1, view2: View2 } } ]})复制代码
mehtods: { routerMethodsCollection() { // router.push // 类似 window.history.pushState,会在history中产生新纪录,回退按钮可退回 // 点击内部调用router.push,故 对应 router.push(...) this.$router.push('/home') // 传入路径字符串 this.$router.push({ path: 'home' }) // 传入路由描述对象 // 路由传参,如果指定了path则会传参失败 this.$router.push({ name: 'user', params: { userId: 123 }}) // 传入路由描述对象 // 带查询参数,变成 /userlist?sex=male this.$router.push({ path: '/userlist', query: { sex: 'male' }}) // router.replace // 类似 window.history.replaceState不会向 history 添加新记录,而是替换掉当前记录,其他与router.push无异 // 对应 router.replace(...) this.$router.replace('/home') // 传入路径字符串 this.$router.replace({ path: 'home' }) // 传入路由描述对象 // router.go // 类似 window.history.go this.$router.go(1) // 前进一步,等同于 history.forward() this.$router.go(-1) // 后退一步,等同于 history.back() this.$router.go(-1) // 后退三步,等同于 history.go(-3) }}复制代码
动态路由匹配也算是一种路由传参,详见第二大点
二、动态路由匹配(相当于路由传参)
最常用的传参方式就是通过以下两种方式:
<router-link>
标签中的to
属性的路由对象传入字段params
router.push
中的路由对象传入字段params
上面两种方式本质上是相同的,只不过是声明式和编程式两种表现
这里需要注意的是,传入的路由对象中,如果传入了path
字段,则params
字段会被忽略。所以当需要传参时,一般传入name
字段来描述路由地址。
// Main.js // 配置路由时注意需传参的路由要进行命名const router = new VueRouter({ routes : [ {path: '/home',component: Home}, {path: '/param',component: Param, name: 'param'} ]})// App.vue// 在模板中,配置路由渲染出口及传参// Param.vue 中接收参数路由传参
主页 声明式传参 复制代码接收的参数:{
{$route.params.msg}}
// 路由重定向// 意味着访问/a会定向到/b,URL也会变为/bconst router = new VueRouter({ routes: [ { path: '/a', redirect: '/b' }, { path: '/c', redirect: {name: 'use'}} ]})// 路由别名// 意味着访问/b会匹配到/a,URL保持为/bconst router = new VueRouter({ routes: [ { path: '/a', component: A, alias: '/b' } { path: '/a', component: A, alias: ['/b', '/c'] } ]})复制代码
// Main.js中const router = new VueRouter({ routes: [ { path: '/home', component: Home, // 【路由守卫beforeEnter】 beforeEnter(to, from, next) { console.log('路由守卫:beforeEnter') // ... next() // 确保要调用 next 方法 } } ]})// 【全局前置守卫beforeEach】router.beforeEach((to, from, next) => { console.log('全局前置守卫:beforeEach') // ... next() // 确保要调用 next 方法,否则钩子就不会被 resolved})// 【全局解析守卫beforeResolve】router.beforeResolve((to, from, next) => { console.log('全局解析守卫:beforeResolve') // ... next() // 确保要调用 next 方法,否则钩子就不会被 resolved})// 【全局后置钩子afterEach】router.afterEach((to, from) => { console.log('全局后置钩子:afterEach') // ...})// Home.vue中export default { // 【组件守卫beforeRouteEnter】 beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this`,可以传一个回调给 next,将组件实例作为参数来访问组件实例 console.log('组件守卫:beforeRouteEnter') next(vm => { // vm即为组件实例 }) }, // 【组件守卫beforeRouteUpdate】 beforeRouteUpdate (to, from, next) { // 在当前路由改变,但是该组件被复用时调用,例如动态路由 // 可以访问组件实例 `this` console.log('组件守卫:beforeRouteUpdate') next() // 确保要调用 next 方法 }, // 【组件守卫beforeRouteLeave】 beforeRouteLeave (to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` console.log('组件守卫:beforeRouteLeave') next() // 确保要调用 next 方法 }, created() { console.log('组件生命周期:created') }, mounted() { console.log('组件生命周期:mounted') }}复制代码
执行顺序
这两天学习vue-router的笔记,后续学习到的地方再做补充,有误的地方求大神指出
作者:Logan70 链接:https://juejin.im/post/5bcf112b6fb9a05ce95c9b36 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。