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')
-