Vue Router 路由进阶

  • 路由的过渡动效

    <router-view> 是基本的动态组件,所以我们可以用 <transition> 组件给它添加一些过渡效果:
    <transition>
       <router-view></router-view>
    </transition> 
    
    Transition 的所有功能 在这里同样适用
    上面的用法会给所有路由设置一样的过渡效果,如果你想让每个路由组件有各自的过渡效果,可以在各路由组件内使用 <transition> 并设置不同的 name
    const Foo = {
       template: `
          <transition name="slide">
             <div class="foo">...</div>
          </transition>
       `
    }
       
    const Bar = {
       template: `
          <transition name="fade">
             <div class="bar">...</div>
          </transition>
       `
    }
    
    还可以基于当前路由与目标路由的变化关系,动态设置过渡效果:
    //HTML code
    <transition :name="transitionName">
       <router-view></router-view>
    </transition> 
    
    
    // 接着在父组件内
    // watch $route 决定使用哪种过渡
    watch: {
      '$route' (to, from) {
        const toDepth = to.path.split('/').length
        const fromDepth = from.path.split('/').length
        this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
      }
    }
    
    查看完整例子请移步这里
  • 滚动行为

    使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。
    注意: 这个功能只在支持 history.pushState 的浏览器中可用。
    当创建一个 Router 实例,你可以提供一个 scrollBehavior 方法:
    const router = new VueRouter({
       routes: [...],
       scrollBehavior (to, from, savedPosition) {
          // return 期望滚动到哪个的位置
       }
    })
    
    scrollBehavior 方法接收 to 和 from 路由对象。第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。
    这个方法返回滚动位置的对象信息,长这样:
    • { x: number, y: number }
    • { selector: string, offset? : { x: number, y: number }} (offset 只在 2.6.0+ 支持)
    如果返回一个 falsy (译者注:falsy 不是 false,参考这里 )的值,或者是一个空对象,那么不会发生滚动。
    scrollBehavior (to, from, savedPosition) {
       return { x: 0, y: 0 }
    }
    
    对于所有路由导航,简单地让页面滚动到顶部。
    返回 savedPosition,在按下 后退/前进 按钮时,就会像浏览器的原生表现那样:
    scrollBehavior (to, from, savedPosition) {
       if (savedPosition) {
          return savedPosition
       } else {
          return { x: 0, y: 0 }
       }
    }
    
    如果你要模拟“滚动到锚点”的行为:
    scrollBehavior (to, from, savedPosition) {
       if (to.hash) {
          return {
             selector: to.hash
          }
       }
    }
    
    你也可以返回一个 Promise 来得出预期的位置描述:
    scrollBehavior (to, from, savedPosition) {
       return new Promise((resolve, reject) => {
          setTimeout(() => {
             resolve({ x: 0, y: 0 })
          }, 500)
       })
    }
    
  • 路由懒加载

    当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
    结合 Vue 的异步组件 和 Webpack 的代码分割功能 ,轻松实现路由组件的懒加载。
    首先,可以将异步组件定义为返回一个 Promise 的工厂函数 (该函数返回的 Promise 应该 resolve 组件本身):
    const Foo = () => Promise.resolve({ /* 组件定义对象 */ })
    第二,在 Webpack 中,我们可以使用动态 import 语法来定义代码分块点 (split point):
    import('./Foo.vue') // 返回 Promise
    如果您使用的是 Babel,你将需要添加 syntax-dynamic-import 插件,才能使 Babel 可以正确地解析语法。
    结合这两者,这就是如何定义一个能够被 Webpack 自动代码分割的异步组件。
    const Foo = () => import('./Foo.vue')
    在路由配置中什么都不需要改变,只需要像往常一样使用 Foo
    const router = new VueRouter({
       routes: [
          { path: '/foo', component: Foo }
       ]
    })
    

    把组件按组分块

    有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk ,一个特殊的注释语法来提供 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')