vue
提供了 <transition>
组件来为组件的切换添加动画,得益于这个特性, vue-router
中的 router-view
也可以在切换路由组件时播放动画。自然的,就产生了在前进/后退时使用不同动画的需求。在 vue-router
文档的 Route-Based Dynamic Transition 一节中,提供了这样的写法:
// then, in the parent component,
// watch the `$route` to determine the transition to use
watch: {
'$route' (to, from) {
const toDepth = to.path.split('/').length
const fromDepth = from.path.split('/').length
this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
}
}
根据路径中 /
的个数来判断路由的深度,然后以此决定播放的动画。但事情并不总是那么简单。
想象一个在线音乐流媒体应用 真的不是这个 ,其中有搜索( /search
),歌手(/artist/:id
),专辑(/album/:id
),歌单(/playlist/:id
)等页面。用户搜索 1 关键词后,通过搜索结果进入歌单 2 页面,然后根据歌单中的歌曲进入歌手 3 页面,再由歌手详情页的专辑列表进入专辑 4 页面。在这期间,累积了这样的导航栈:
/search
/playlist/:id
/artist/:id
/album/:id
此时,如果用户选择返回,根据上面的代码计算出的路由 3 与 4 的“层级”相同,用户将看到与导航前进时完全相同的动画,这很反直觉。如果觉得这样的表述不够直观,可以看这个 fiddle 。
所以 vue-router
就真的没有一个导航栈吗?还真就没有。甚至还在 GitHub 上找到了一个 6012 年的上古 Issue ,然后惊奇地发现它被列在了 Todo in 3.x 中。
怎么办?vue-router
提供了一个 abstract
模式,由数组保存所经过的路由,可以由 $router.history.stack
访问到。具体的细节可以参见源码。感觉这本来是提供给没有 浏览器 API 的 SSR 环境用的,不过这里也可以适用。不过有个缺点:使用 abstract
模式后,任何的路由变化都不会体现在地址栏上, URL 将不会有任何变化。反正 Electron 本来就看不见地址栏
至于实现,请看这个 fiddle 。值得注意的是,abstract
模式的 vue-router
在使用前需要先手动 push
一个路由进去,否则路径会是空的。
(这似乎是这个博客建立以来的第一篇正经的前端文章呢 ... 有点尴尬 ...)
最近一直在肝 Electron NCM ,用上了网易云新版 eapi ,常用的功能都写得差不多了,只剩一些我基本不用的什么私人 FM 啦,榜单啦,用户关注啦之类的。哦其实也不能看评论,不过用桌面版客户端听歌的时候一般都是在写代码嘛,哪有空看评论啊 ...
这篇文章也是对开发时解决问题的记录,这是一个真实的需求!不过这个项目中有更复杂的动画逻辑,比如播放器界面的展开/折叠之类的。详情可以看这一段。
好了,不多说,该睡了。