# 标签栏导航

目前方案大致为: 运用 keep-alive 和 router-view 的结合。代码在 src/layout/components/AppMain.vue。

<keep-alive :include="cachedViews">
  <router-view></router-view>
</keep-alive>

顶部标签栏导航实际作用相当于 nav 的另一种展现形式,都是一个个 router-link,点击跳转到相应的页面。然后我们通过监听路由 $route 的变化,来判断当前页面是否需要重新加载或者已被缓存。

# visitedViews && cachedViews

目前 tags-view 维护了两个数组。

  • visitedViews: 用户访问过的页面,是标签栏导航显示的一个个 tag 数组集合。
  • cachedViews: 实际 keep-alive 的路由。可以在配置路由的时候通过 meta.noCache 设置是否缓存这个路由,默认都缓存。

# 注意事项

keep-alive 和 router-view 是强耦合的,而且 keep-alive 的 include 默认优先匹配组件的 name,我们在编写路由 router 和路由对应的 view component 的时候要确保两者的 name 是完全一致的。name 命名尽量保证唯一性,不要和某些组件的命名重复,否则会造成递归引用内存溢出等问题。如果不写 name 就不会被缓存。

// router 路由声明
{
  path: 'create-form',
  component: ()=>import('@/views/form/create'),
  name: 'createForm',
  meta: { title: 'createForm', icon: 'table' }
}
// 路由对应的 view
export default {
  name: 'createForm'
}

# 缓存不适合场景

目前缓存的方案对于某些业务是不适合的,例如文章详情页 /article/1 /article/2,它们的路由不同但对应的组件却是一样的,所以它们的组件 name 就是一样的,而 keep-alive 的 include 只能根据组件名进行缓存,所以就有问题。目前有两种解决方案:

  • 不使用 keep-alive 的 include 功能,直接用 keep-alive 缓存所有组件,这样就支持此业务情况。 在 src/layout/components/AppMain.vue 移除 include 相关代码即可。直接使用 keep-alive 也有弊端,它不能动态地删除缓存,可以设置一个最大缓存实例的个数 limit。
  • 使用 localStorage 等浏览器缓存方案进行缓存处理。

# Affix 固钉

当声明路由添加了 Affix 属性,当前 tag 被固定在 tags-view 中。

{
  path: '/',
  component: Layout,
  redirect: '/workbench',
  name: 'home',
  meta: { title: 'home', icon: 'el-icon-s-home' },
  children: [
    {
      path: '/workbench',
      component: () => import('@/views/home/index'),
      name: 'Workbench',
      meta: { title: 'workbench', icon: 'dashboard', affix: true }
    }
  ]
}

# 移除

如果没有标签导航栏需求,可以移除此功能。首先找到 src/layout/components/AppMain.vue 移除 keep-alive

<template>
  <section class="app-main" style="min-height: 100%">
    <transition name="fade-transform" mode="out-in">
      <router-view></router-view>
    </transition>
  </section>
</template>

然后移除整个 src/layout/components/TagsView 文件夹,并在 src/layout/components/index.js 和 src/layout/index.vue 移除相应的依赖,最后把 src/store/modules/tagsView.js 删除即可。