VUE 提供了一个内置的组件 keep-alive来缓存组件内部的状态,避免组件重新渲染组件。但是在开发过程中,并不是所有的组件都需要被缓存,于是就用到keep-alive的两个属性

keep-alive属性:

include - 字符串或正则表达式。只有匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何匹配的组件都不会被缓存。

keep-alive用法

1.缓存不活动的动态组件

<keep-alive>
  <component :is="view"></component>
</keep-alive>

2.缓存匹配到的路由
将匹配到的路由下的组件,以及组件包裹的组件,都缓存起来
方式一:vue文件中

<keep-alive>
    <router-view></router-view>
</keep-alive>

方式二:router.js

  {
      path: "/",
      redirect: "/index/artical", 
      component: resolve => require(['@/components/index'], resolve),
      meta: {
        title: "store.state.nickname",
        keepAlive: true// 需要被缓存
      }
    },

那么问题来了,如果在需要被缓存的组件中,有一部分组件不需要被缓存。
如需要被缓存的组件A中包裹了组件b和c,这时我需要缓存组件A中的b而不缓存c该怎么办呢

解决办法1

<keep-alive include="a">
 <component>
  <!-- name 为 a 的组件将被缓存! -->
 </component>
</keep-alive>可以保留它的状态或避免重新渲染

<keep-alive exclude="a">
 <component>
  <!-- 除了 name 为 a 的组件都将被缓存! -->
 </component>
</keep-alive>可以保留它的状态或避免重新渲染

<keep-alive include="a">
  <router-view>
    <!-- 只有路径匹配到的视图 a 组件会被缓存! -->
  </router-view>
</keep-alive>

**缺点:**需要组件的名称,在较为大型且复杂的企业项目中就比较麻烦。

解决办法2

// routes 配置
export default [
 {
  path: '/',
  name: 'home',
  component: Home,
  meta: {
   keepAlive: true // 需要被缓存
  }
 }, {
  path: '/:id',
  name: 'edit',
  component: Edit,
  meta: {
   keepAlive: false // 不需要被缓存
  }
 }

在页面中

<keep-alive>
  <router-view v-if="$route.meta.keepAlive">
    <!-- 这里是会被缓存的视图组件,比如 Home! -->
  </router-view>
</keep-alive>

<router-view v-if="!$route.meta.keepAlive">
  <!-- 这里是不被缓存的视图组件,比如 Edit! -->
</router-view>

升级版

假如现在有这样的需求:有三个页面,文章列表页面,文章详情页面,文章新增页面。从文章新增页面到文章列表页面是要刷新文章列表页面。从文章详情页面到文章列表页面是不需要刷文章列表页面。默认显示文章列表页面(听起来有点绕口哈哈)
这时候要用到beforeRouteLeave

在文章列表页面设置路由

{
  path: '/',
  name: 'A',
  component: A,
  meta: {
    keepAlive: true // 需要被缓存
  }
}

在文章新增页面组件中,设置beforeRouteLeave

export default {
  data() {
    return {};
  },
  methods: {},
  beforeRouteLeave(to, from, next) {
     // 设置下一个路由的 meta
    to.meta.keepAlive = false; // 让 文章列表 不缓存,即刷新
    next();
  }
};

在文章详情页面组件中

export default {
  data() {
    return {};
  },
  methods: {},
  beforeRouteLeave(to, from, next) {
    // 设置下一个路由的 meta
    to.meta.keepAlive = true; // 让 文章列表页面 缓存,即不刷新
    next();
  }
};
Logo

前往低代码交流专区

更多推荐