当前位置:   article > 正文

vue3 自定义tabbar 缓存当前页面的数据_vue tabs标签页缓存

vue tabs标签页缓存

整体思路

1. 封装自定义tabbar组件 需要监听当前的路由路径,当路由发生变化的时候,需要存tabslist和 keepaliveName的数据

2. 封装存储和移除tabsList的数据的方法(pinia)用于显示页签

3. 封装缓存和移除的组件名字keepaliveName的方法(pinia)用于keepalive组件的include属性

4. 在路由出口的位置需要使用keepalive组件和component组件 缓存组件的数据 实现切换tab后,上一tab页的内容仍然保留

第一步  封装自定义tabbar组件

  1. <div class="tabs-box">
  2. <div class="tabs-menu">
  3. <el-tabs
  4. v-model="tabsMenuValue"
  5. type="card"
  6. @tab-click="tabClick"
  7. @tab-remove="tabRemove"
  8. >
  9. <el-tab-pane
  10. v-for="item in tabsMenuList"
  11. :key="item.path"
  12. :label="item.title"
  13. :name="item.path"
  14. :closable="item.close"
  15. >
  16. <template #label>
  17. <el-icon class="tabs-icon" v-show="item.icon && tabsIcon"></el-icon>
  18. {{ item.title }}
  19. </template>
  20. </el-tab-pane>
  21. </el-tabs>
  22. </div>
  23. </div>
  24. // Tab Click 点击每一个tab跳转到对应的页面
  25. const tabClick = (tabItem: TabsPaneContext) => {
  26. const fullPath = tabItem.props.name as string
  27. console.log('fullPath', fullPath)
  28. router.push(fullPath)
  29. }
  30. // Remove Tab 点击每一个tab上的icon移除当前tab
  31. const tabRemove = (fullPath: TabPaneName) => {
  32. //tab-remove方法 会返回一个回调函数 fullpath
  33. console.log('fullPath', fullPath)
  34. const name =
  35. tabStore.tabsMenuList.filter((item: any) => item.path == fullPath)[0]
  36. .name || ''
  37. // 移除keepaliveName和tabsList的数据
  38. keepAliveStore.removeKeepAliveName(name)
  39. tabStore.removeTabs(fullPath as string, fullPath == route.fullPath)
  40. }
  41. // 监听路由的变化(防止浏览器后退/前进不变化 tabsMenuValue)
  42. watch(
  43. () => route.fullPath,
  44. () => {
  45. const routeList = route.fullPath.split('/')
  46. const name = routeList[routeList.length - 1]
  47. tabsMenuValue.value = route.fullPath
  48. const tabsParams = {
  49. icon: route.meta.icon as string,
  50. title: route.meta.title as string,
  51. path: route.fullPath,
  52. name: name as string,
  53. close: true,
  54. }
  55. // 当路由发生变化时 给tabsList 和 keepaliveName中添加数据
  56. tabStore.addTabs(tabsParams)
  57. keepAliveStore.addKeepAliveName(name)
  58. },
  59. // 一来进来页面就监听
  60. { immediate: true },
  61. )

第二步  封装存储和移除tabsList的数据的方法

  1. // addtab
  2. async addTabs(tabItem: TabsMenuProps) {
  3. //要往tabsList添加的tab 是否在list中,如果不在就添加
  4. console.log('tabItem', tabItem)
  5. const res1 = this.tabsMenuList.every((item) => {
  6. console.log('item', item)
  7. return item.path !== tabItem.path
  8. })
  9. console.log('res1', res1)
  10. if (this.tabsMenuList.every((item) => item.path !== tabItem.path)) {
  11. this.tabsMenuList.push(tabItem)
  12. console.log('tabsMenuList', this.tabsMenuList)
  13. }
  14. },
  15. // Remove Tabs
  16. async removeTabs(tabPath: string, isCurrent: boolean = true) {
  17. // isCurrent 判断当前的fullpath和路由获取到的fullpath 是否一致
  18. // 1. 把当前tabs关闭
  19. // 2. 显示上一个tabs内容
  20. const tabsMenuList = this.tabsMenuList
  21. if (isCurrent) {
  22. tabsMenuList.forEach((item, index) => {
  23. if (item.path !== tabPath) return
  24. // ?什么情况下会 加1 显示上一个tabs内容
  25. const nextTab = tabsMenuList[index + 1] || tabsMenuList[index - 1]
  26. if (!nextTab) return
  27. router.push(nextTab.path)
  28. })
  29. }
  30. //把当前tabs关闭
  31. this.tabsMenuList = tabsMenuList.filter((item) => item.path !== tabPath)
  32. },

第三步 封装缓存和移除的组件名字keepaliveName的方法

  1. // Add KeepAliveName
  2. async addKeepAliveName(name: string) {
  3. !this.keepAliveName.includes(name) && this.keepAliveName.push(name)
  4. // console.log('keepAliveName3333333', this.keepAliveName)
  5. },
  6. // Remove KeepAliveName
  7. async removeKeepAliveName(name: string) {
  8. this.keepAliveName = this.keepAliveName.filter((item) => item !== name)
  9. },

第四步  在路由出口的位置缓存数据

  1. <router-view v-slot="{ Component }">
  2. <!-- transition 过渡动画 -->
  3. <transition name="fade">
  4. <!-- 渲染layout一级路由组件的子路由 -->
  5. <!--:key 每次切换时,通过修改 key 的值,可以避免缓存中的组件被复用,从而达到刷新组件的目的-->
  6. <keep-alive :include="keepAliveName">
  7. <component :is="Component" v-if="flag" :key="route.path" />
  8. </keep-alive>
  9. </transition>
  10. </router-view>

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号