vue-router知识点总结

简介

1、嵌套的路由/视图表;
2、模块化的、基于组件的路由配置;
3、路由参数、查询。通配符;
4、基于vue.js过滤系统的视图过滤效果;
5、细粒度的导航控制;
6、带有自动激活的css class的链接;
7、HTML5历史模式或hash模式,在ie9中自动降级;
8、自定义的滚动条行为

安装(v3.x)

安装依赖:
npm install vue-router@3.0.1 --save

  • –savedependencies 键下,发布后还需要依赖的模块,譬如像Echarts库或者Vue框架类似的,我们在开发完后后肯定还要依赖它们,否则就运行不了。
  • –save-devdevDependencies 键下,开发时的依赖比如安装 js的压缩包gulp-uglify 因为我们在发布后用不到它,而只是在我们开发才用到它。

以vue2.x为例,有如下文件,打开index.js文件
在这里插入图片描述

  • 在文件中引入vue,
  • 引入vue-router,
  • 引入所需要的导航的页面路径,
  • 使用路由vue.use(Router),
  • 创建Router实例
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wCBJ7x9y-1650529874715)(/images/pasted-231.png)]
  • 在main.js中引入router.js,注册:import router from ‘./router’;
new Vue({
    	el: '#app',
    	router,// es6方式,key和value相同时,只写一个就行
    	components: {App},
    	template: '<App/>'
	});
安装使用(v4.x)

vue-router如果使用v4.x版本,vue需要使用v3.x版本,如果vue使用v2.x版本,启动项目会报警告
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iQ1zPQSZ-1650529874715)(/images/pasted-235.png)]
使用方式:略~

基础

动态路由匹配

  • 动态路径参数,以冒号开头。像/user/foo和/user/bar都将映射到相同的路由。
    一个“路径参数”使用冒号:标记。当匹配到一个路由时,参数值会被设置到this.$route.params,可以在每个组件内使用。
    注意:当使用路由参数时, 例如从/user/foo导航到/user/bar,原来的组件实例会被复用,意味着组件的生命周期钩子不会再被调用,如果想对路由的变化做出响应的话,可以用watch监听路由或者导航守卫beforeRouteUpdate。
    {path: '/user/:id', component: User}
    - 跳转user路由时:this.$router.push({name: 'user', params: {id: '33333333'}})
    this.$router.push({path: '/user/33333'})等;
    - 跳转其他页面路由的时候,不能使用this.$router.push('test'),可以使用this.$router.push('/test')或者对象形式;
    
  • 路由通配符(*)匹配。 当使用一个通配符时,$route.params内会自动添加一个名为pathMatch参数。
会匹配所有路径,通常用于客户端404错误。当使用通配符路由时,含有通配符的路由应该放在最后。
{path: '*'}
会匹配以/user-开头的任意路径
{path: '/user-*'}

嵌套路由

route中使用children添加嵌套路由
注意:/开头的嵌套路径会被当做根路径。这让你充分的使用嵌套组件而无须设置嵌套的路径

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
        }
      ]
    }]
  })

编程式的导航

声明式导航:

<router-link :to="{name: 'user', params?: {id: 'test'}}">
<router-link :to="{path: 'user', query?: {id: '1111'}}">

编程式导航:

- 参数location
	* 字符串this.$router.push('home');
    * 对象this.$router.push({path: 'home', query?: {id: '1111'}})参数会拼在url后面
    * 命名的路由this.$router.push({name: 'user', params?: {id: '2222'}})参数不会拼在url后面
- 参数onComplete回调将会在导航成功完成(在所有的异步钩子被解析之后)的时候进行调用。
- 参数onAbort回调将会在导航终止(导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由)的时候进行调用。
this.$router.push(location, onComplete?,onAbort?)
this.$router.replace(location, onComplete?,onAbort?)

- 在浏览器记录中前进一步,参数为整数
this.$router.go(1) => history.forward()

- 在浏览器记录中后退一步,参数为整数
this.$router.go(-1) => history.back()

命名路由

const router = new VueRouter({
  routes: [{
    path: '/user/:userId',
    // 命名路由
    name: 'user',
    component: User
  }]
})

命名视图

一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件,components的配置需要带上s,如果router-view没有设置名字,那么默认为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>

const router = new VueRouter({
  routes: [{
     path: '/',
     components: {
       default: Foo,
       a: Bar,
       b: Baz
     }
  }]
})

命名视图也可以嵌套

{
  path: '/settings',
  // 你也可以在顶级路由就配置命名视图
  component: UserSettings,
  children: [{
    path: 'emails',
    component: UserEmailsSubscriptions
  }, {
    path: 'profile',
    components: {
      default: UserProfile,
      helper: UserProfilePreview
    }
  }]
}

重定向和别名

重定向:当用户访问/a时,URL将会被替换成/b,然后匹配路由为/b

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})
const router = new VueRouter({
  routes: [
    // 也可以是一个命名的路由
    { path: '/a', redirect: { name: 'foo'}}
  ]
})
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: to => {
      // 方法接收 目标路由(也就是'/a') 作为参数
      // return 重定向的 字符串路径/路径对象
    }}
  ]
})

别名:/a的别名是/b,当用户访问/b时,URL会保持为/b,但是路由匹配则为/a,渲染/a的页面,就像用户访问/a一样

const router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' },
    // 所有的 alias 和 path 值必须共享相同的参数。
    { path: '/user/:id', component: A, alias: '/u/:id' }
  ]
})

路由组件传参

使用props将组件和路由解耦,取代与$route的耦合

const router = new VueRouter({
  routes: [
    { 
      path: '/user/:id', 
      component: User, 
      // 布尔模式,path: '/user/:id'
      props: true 
      // 对象模式,path: '/user'
      props: {id: '777777'}
      // 函数模式,path: '/user'
      props: route => ({query: route.query.q})
    },
    // 对于包含命名视图的路由,你必须分别为每个命名视图添加props选项:
    {
      path: '/user/:id',
      components: { default: User, sidebar: Sidebar },
      props: { default: true, sidebar: false }
    }
  ]
})

const User = {
  props: ['id'],
  template: '<div>User {{ id }}</div>'
}

HTML5 history模式

因为单页应用只用一个html文件;history需要配合后端配置;不然当重新刷新就会报错404。我们需要在服务器配置,如果URL匹配不到任何静态资源,就跳转到默认的index.html
当使用history模式时,URL就像正常的url,没有#。

进阶

导航守卫

  • 全局前置守卫router.beforeEach((to, from, next) => {})

    • 参数to:即将要进入的目标路由对象
    • 参数from:当前导航正要离开的路由
    • 参数next:调用此方法resolve这个钩子。执行效果依赖next方法的调用参数
      • next()进行管道中的下一个钩子,如果全部钩子执行完了,则导航的状态就是confirmed。
      • next(false)中断当前的导航。如果浏览器的URL改变了(可能是用户手动或者浏览器后退按钮),那么URL地址会重置到from路由对应的地址。
      • next(‘/’)或者next({path: ‘/a’})跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向next传递任意位置对象,且允许设置例如 replace: truename: 'home' 之类的选项以及任何用在 router-linkto prop或者 router.push() 中的选项。
      • next(error)如果传入next的参数是一个error实例,则导航会被终止且改错误会被传递给 router.onError() 注册过的回调。
  • 全局解析守卫router.beforeResolve((to, from, next) => {})
    与router.beforeEach类似,是获取数据或者执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。

  • 全局后置钩子router.afterEach((to, from) => {})

  • 路由独享的守卫
    只在进入路由时触发,不会在params,query或者hash改变时触发,他们只有在从一个不同的路由导航时,才会被触发。

    const routes = [
      {
        path: '/users/:id',
        component: UserDetails,
        beforeEnter: (to, from) => {
          // reject the navigation
          return false
        }
      },
      {
        path: '/about',
        component: aboutDetails,
        beforeEnter: [removeQueryParams]
      }
    ]
    function removeQueryParams(to) {
      if (Object.keys(to.query).length)
        return { path: to.path, query: {}, hash: to.hash }
    }
    
    
  • 组件内的守卫

    • beforeRouteEnter:在渲染该组件的对应路由被验证前调用;不能获取组件实例this,因为当守卫执行时,组件实例还没有被创建。是支持给next传递回调的唯一守卫。
    beforeRouteEnter (to, from, next) {
      next(vm => {
        // 通过 `vm` 访问组件实例
        vm.id = '1111'
      })
     }
    
    • beforeRouteUpdate:在当前路由改变,但是该组件被复用时调用。可以访问this
    • beforeRouteLeave:在导航离开渲染该组件的对应路由时调用。可以访问this
  • 完整的导航解析流程

    • 导航被触发;
    • 在失活的组件里调用beforeRouteLeave守卫;
    • 调用全局beforeEach守卫;
    • 在重用的组件里调用beforeRouteUpdate守卫;
    • 在路由配置里调用beforeEnter
    • 解析异步路由组件;
    • 在被激活的组件里调用beforeRouteEnter;
    • 调用全局的beforeResolve守卫;
    • 导航被确认;
    • 调用全局的afterEach钩子;
    • 触发DOM更新;
    • 调用beforeRouteEnter守卫中传给next的回调函数,创建好的组件实例会作为回调函数的参数传入。

路由元信息

定义路由的时候可以配置 meta 字段,将任意信息附加到路由上。
一个路由匹配到的所有路由记录会暴露为 r o u t e 对 象 的 ‘ route对象的 ` routeroute.matched数组。我们需要遍历这个数组来检查路由记录中的meta字段。 vue Router还提供了一个$route.meta` 方法,他是一个非递归合并所有meta字段的方法。

const routes = [{
   path: '/posts',
   component: PostsLayout,
   children: [{
     path: 'new',
     component: PostsNew,
     // 只有经过身份验证的用户才能创建帖子
     meta: { requiresAuth: true }
   }]
 }]

过渡效果

  • v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除;
  • v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用。在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数;
  • v-enter-to:定义进入过渡的结束状态。在元素被插入之后下一帧生效(与此同时v-enter被移除),在过渡/动画完成之后移除;
  • v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除;
  • v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数;
  • v-leave-to:定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
const routes = [{
    path: '/custom-transition',
    component: PanelLeft,
    meta: { transition: 'fade' },
  },{
    path: '/other-transition',
    component: PanelRight,
    meta: { transition: 'fade' },
  }]
// 每个路由的组件有不同的过渡,你可以将元信息和动态的name结合在一起,放在<transition>上
<transition :name = "$route.meta.transition">
    <router-view/>
</transition>
.fade-enter-active, .fade-leave-active {
   transition: opacity 2s
}
.fade-enter, .fade-leave-to {
   opacity: 0
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q7YBA7is-1650529874716)(/images/pasted-224.png)]

数据获取

有时候,进入某个路由后,需要从服务器获取数据。例如,在渲染用户信息时,你需要从服务器获取用户的数据。通过两种方式实现:

  • 导航完成之后获取:先完成导航,然后再接下来的生命周期钩子中获取数据,在数据获取期间显示加载中之类的提示;
  • 导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在获取成功后执行导航。

滚动行为(v3.x)

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // 返回 savedPosition,在按下 后退/前进 按钮时,就会像浏览器的原生表现那样,不触发滚动:
    if (savedPosition) {
        return savedPosition
    } else {
        // return 期望滚动到哪个的位置
        return { x: 0, y: 0 }
    }
  }
})
滚动行为(v4.x)
// 创建router文件的时候,需要引入import {createRouter,createWebHashHistory} from 'vue-router';
const router = createRouter({
  history: createWebHashHistory(),
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // return 期望滚动到哪个的位置
    // return { top: 100 }
    // 始终在元素 #main 上方滚动 10px
    return {
      // 也可以这么写
      // el: document.getElementById('main'),
      el: '#main',
      top: -10,
    }
  }
})

路由懒加载

当打包构建应用时,js包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

懒加载简单来说就是延迟加载或按需加载,即在需要的时候的时候进行加载。

  • 像vue这种单页面应用,如果没有应用懒加载,运用webpack打包后的文件将会异常的大;
  • 造成进入首页时,需要加载的内容过多,时间过长,会出现长时间的白屏,即使做了loading也不理想;
  • 运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时;
  • 进入页面不用也不需要一次性加载过多资源造成加载时间过程。
const Foo = () => import('./Foo.vue')
const router = new VueRouter({
  routes: [{ path: '/foo', component: Foo }]
})

打包之后的文件区别:比不使用路由懒加载的情况,多了各个页面的js

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LeNvVR9P-1650529874716)(/images/pasted-236.png)]

把组件按组分块

有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk (opens new window),一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值