21

前言

前段时间呢实现了一个模仿移动端app的通过滑动来切换路由/tab的效果,详见vuejs实现spa页面组件滑动特效。完了之后呢就在想能不能做成一个组件的形式,改进一下,抽离出来,顺便再发布到npm上,不是美滋滋?这两天正好有时间,就把它写出来了,我给他起名叫tab-slider,中间遇到一些坑,分享一蛤。

正文

简单介绍

正如我上一篇文章所说,如果你需要这种功能

  1. 即将离开的组件和将要进入的组合需要同时出现在页面中
  2. 用手指拖动页面可以切换路由,而不仅仅是点击链接跳转
  3. 结合以上两点,拖动过程中同时显示两个组件,手指离开屏幕后执行切换路由或者返回的动作

tab-slider也许可以满足你,具体实现思路可以去看上一篇文章,这里就不讲了,来看一下效果图:
预期效果

改进方面

  • 相比之前每个路由组件都要写touch事件的蠢写法,我把touch事件写在了router-view上,增强了代码的复用,事实上不这么改我也没法将组件抽离出来给别人用
  • 支持多个tab切换,之前是只有2个,写法固定,现在可以有任意个tab切换。

踩过的坑

在我开发XiXi这个仿DiDi app项目的时,我使用的Vue版本是2.4.4,而我写tab-slider的时候使用了最新版本的Vue 2.5.16。写完之后我遇到了一个问题,滑动完毕切换路由的时候,router-view所对应的区域会闪一下,而通过点击router-link切换路由则不会。
Vue2.5.16效果图:
实际效果

where?哪有问题?

这里一开始我觉得可能是新老项目css样式做了部分更改,影响了浏览器的重绘或是回流,苦苦搜寻无果。后来通过chrome控制台的的performance发现:新版本的vue多了个flushCallbacksactivity,耗时9ms。这是什么?继续google,没什么有用的东西,ok没关系,去Vue仓库里搜,发现他第一次写入是在14 Oct 2017,也就是Vue2.5.2发布的时候,这个版本修改了nextTick实现机制,并关闭了一个issue,有兴趣的同学可以看看。这个issue下面呢又有人reference了这个issue,里面正好讲解了相关内容。开源社区简直棒极了!

why?问题是什么?

简单来说呢就是新版Vue对于DOM相关事件是放在macro task里,其他情况默认走micro task,而micro task要先于macro task执行。而我项目中的写法是,对拖曳的dom监听了transitionend事件,当transition结束后进行路由切换。所以原因应该是滑动结束后(也就是transition结束),路由没有在第一时间进行跳转,所以出现了一瞬间的“白屏”,在我们看来就是闪了一下。

how?怎么解决?

  • solution1: 使用低版本Vue,2.4.4及以下。
  • solution2: 修改写法,直接使用settimeout,延迟时间与动画时间一致,而由于js的异步机制,实际延迟时间总是略大于写入的延迟时间,基本上能达到想要的效果。

这里我采用了solution2,毕竟是写出来给人用了,总要有个通用的解决方案。

另外个坑就是在发布到npm之后,引入我的包,没法正常使用,提示组件未注册,折腾了许久,参考了vantcube-ui的组件导出方式,却一直没能成功导出正确的对象。最后发现原因在于webpack的配置上: 需要在output属性中添加library以及libraryTarget,这样才能正确导出对象。

怎么用

说了那么多废话,这组件怎么用?

  • 安装:npm i -S tab-slider
  • main.js中引入样式,import 'tab-slider/dist/index.css'
  • 在需要的组件中注册子组件,import TabSlider from 'tab-slider',也可以在main.js中引入,并通过Vue.use()来使之成为一个全局组件。
  • 接受一个comp的prop,类型是数组,数组中的每一项是对象,对象中又包含了namecomponent属性。其中name属性必须和路由名字相同,(这也意味着你必须为每个路由取名),component则是对应的组件。这里要注意一下,comp中每一项的顺序需要与你的router-link顺序一一对应。
  • 还接受一个default-index,表示默认跳转的路由,从0开始。

可以改进的地方

  • webpack相关配置还是通过vue-cli生成的,删除了一些不必要的东西,但还是没有做到最简。打包出来的东西也有9kb,好像有点大的过分。
  • 可以把router-link的内容也直接做进去,毕竟tab和内容区是紧密联系的。
  • 提供更多的选项(prop)给使用者。

么得了

如果对你有帮助的话点个赞点个收藏点个star提个issue都是可以的哦 仓库地址


HaHa
525 声望11 粉丝