Vue 路由页签组件推荐:Vue Router Tab

5,975 阅读2分钟
vue-router-tab logo

Vue Router Tab 是基于 Vue Router 的路由页签组件,用来实现多页签页面的管理。

该项目已经成立一年多了,目前最新版本 1.2.0,已经完成了自己预期的绝大多数功能,api 相对比较稳定了。希望自己的开源成果能帮助到有需要的朋友。

旧的版本,RouterTab 参考 KeepAlive 自行实现了缓存控制的组件 RouterAlive,来解决各种路由缓存的问题。

在新的版本,RouterAlive 已经基于原生的 KeepAlive 和 RouterView 重构,支持更强大的路由缓存控制和管理。后续会有计划单独开源 RouterAlive 组件,开放给更多人使用。

🔗 相关链接

项目地址:

github.com/bhuh12/vue-…

📝 文档

📺 Demo 演示

👨‍💻 示例项目

📃 更新日志


📌 已支持的功能

✅ 响应路由变化来打开或切换页签

✅ 页签过多鼠标滚轮滚动

✅ 页签拖拽排序

✅ 支持页签打开、切换、关闭、刷新、重置等操作

Iframe 页签嵌入外部网站

✅ 组件个性化设置:过渡效果自定义插槽页签右键菜单

多语言支持

缓存控制:页签规则、页签是否缓存、最大缓存数、是否复用组件等

动态页签信息:标题、图标、提示

初始页签数据,进入页面时默认显示的页签

页签刷新还原,在浏览器刷新后恢复页签

页面离开前确认

Nuxt 支持


解决方案

Vue Router Tab 实现过程中遇到的问题及解决方案,也欢迎提出更好的点子。

  1. 相同路由需要根据 route.paramsroute.query 不同,根据规则生成不同的缓存(同一路由页签多开):

    <router-view> 添加 key 属性,根据 key 不同生成不同的实例。

  2. 通过 <keep-alive> 组件实例,精准控制缓存:

    1. 获取 <keep-alive> 实例:

      <transition> 过渡组件包裹下,通过 this._vnode.children[0].child._vnode.componentInstance 获取 <keep-alive> 组件实例。

    2. 匹配并移除缓存:

      1. 根据缓存 $alive.cache[i].data.key 来匹配缓存。

      2. 销毁当前缓存组件实例:$alive.cache[key].componentInstance.$destroy()

      3. $alive.keys 数组中移除当前 key

  3. 页面组件强制刷新:

    1. 移除当前页面组件缓存。

    2. router-view 组件通过 v-if 隐藏,在过渡效果结束或 nextTick 后再显示。

  4. 获取当前组件所在的路由深度:

    递归查找最近的拥有 $vnode.data.routerViewDepth 的父组件的相应值。

  5. 嵌套路由 <router-view>key,如果直接从 $route 中获取,子路由切换时会生成不同缓存:

    应该从 $route.matched 中匹配当前嵌套深度所在路由的 path

  6. 打开开启缓存的嵌套路由的一个子路由页面 a,然后访问其他路由页面,再直接访问嵌套路由的另一个子路由页面 b,此时展示的依然是 a,与路由地址不匹配

    通过 activated 钩子,页面组件执行 $forceUpdate 强制更新。

    副作用:子路由页面 a 仍会触发 activated 钩子

  7. iframe 页面页签切换后会重新加载:

    1. <iframe> 节点放在页面所在 <router-view> 的外层,通过 v-show 控制显示隐藏。

    2. 建立 iframe 路由页面组件,通过生命周期钩子来添加、显示、隐藏、移除 <iframe> dom 节点。

  8. 打包后的 js 文件太庞大:

    构建库时,配置 babel.config.jsuseBuiltInsfalse,打包时不包含 Polyfill。