当前位置: > > > Vue.js - 路由 vue-router 的使用详解5(keep-alive使用1:缓存组件)

Vue.js - 路由 vue-router 的使用详解5(keep-alive使用1:缓存组件)

    <keep-alive>Vue 的内置组件,它能在组件切换过程中将状态保存在内存中,防止重复渲染 DOM。下面通过样例进行演示。

一、配合组件使用

1,使用样例

(1)效果图
  • 这是一个简单的 Tab 标签切换效果。当标签切换时,下方的两个自定义组件会随之切换显示。
  • 由于两个子组件是包裹在 <keep-alive> 中,可以看到它们来回切换后,原来页面的内容和数据仍然保留,说明组件消失时并没有被销毁,而是缓存起来。

(2)样例代码
  • 子组件1(child1.vue
<template>
  <div>
    <h3>子页面1</h3>
    <input type="text" name="" value="">
  </div>
</template>
<script>
  export default {
    name: 'child1',
    data() {
      return {
      }
    },
    //keep-alive钩子函数:组件被激活时调用
    activated() {
      console.log('子页面1被激活');
    },
    //keep-alive钩子函数:组件消失,被缓存时调用
    deactivated() {
      console.log('子页面1被缓存');
    }
  }
</script>

  • 子组件2(child2.vue
<template>
  <div>
    <h3>子页面2</h3>
    <input type="text" name="" value="">
  </div>
</template>
<script>
  export default {
    name: 'child2',
    data() {
      return {
      }
    },
    //keep-alive钩子函数:组件被激活时调用
    activated() {
      console.log('子页面2被激活');
    },
    //keep-alive钩子函数:组件消失,被缓存时调用
    deactivated() {
      console.log('子页面2被缓存');
    }
  }
</script>

  • 主页面(index.vue
<template>
  <div>
    <div class="navi">
      <div :class="{'selected':index === 1}" @click="changeIndex(1)">Tab1</div>
      <div :class="{'selected':index === 2}" @click="changeIndex(2)">Tab2</div>
    </div>
    <div class="container">
      <keep-alive>
        <Child1 v-if="index === 1">
        </Child1>
        <Child2 v-else>
        </Child2>
      </keep-alive>
    </div>
  </div>
</template>
<script>
  import Child1 from './child1.vue';
  import Child2 from './child2.vue';

  export default {
    data() {
      return {
        index: 1, //当前选中标签页索引
      }
    },
    components: {
      Child1,
      Child2,
    },
    methods: {
      changeIndex(index) {
        this.index = index;
      }
    }
  }
</script>
<style>
  .navi {
    height: 60px;
    line-height: 60px;
    display: flex;
    border-bottom: 1px solid #e5e5e5;
  }

  .navi > div {
    flex: 1;
    text-align: center;
  }

  .selected {
    color: red;
  }
</style>

(3)上面主页面(index.vue)的代码可以换种写法,改成动态组件,效果也是一样的。
<template>
  <div>
    <div class="navi">
      <div :class="{'selected':index === 1}" @click="changeIndex(1)">Tab1</div>
      <div :class="{'selected':index === 2}" @click="changeIndex(2)">Tab2</div>
    </div>
    <div class="container">
      <keep-alive>
        <component :is="currentView"></component>
      </keep-alive>
    </div>
  </div>
</template>
<script>
  import Child1 from './child1.vue';
  import Child2 from './child2.vue';

  export default {
    data() {
      return {
        index: 1, //当前选中标签页索引
        currentView: "Child1"
      }
    },
    components: {
      Child1,
      Child2,
    },
    methods: {
      changeIndex(index) {
        this.index = index;
        this.currentView = "Child" + index;
      }
    }
  }
</script>
<style>
  .navi {
    height: 60px;
    line-height: 60px;
    display: flex;
    border-bottom: 1px solid #e5e5e5;
  }

  .navi > div {
    flex: 1;
    text-align: center;
  }

  .selected {
    color: red;
  }
</style>

2,钩子函数

(1)<keep-alive> 提供了如下两个生命周期钩子函数:
  • activated():组件被激活时调用。即组件第一次渲染时会被调用,之后每次 keep-alive 激活时也会被调用。通常我们可以在这个方法中实现:每次进入页面的时候获取最新的数据。
  • deactivated():组件被停用时调用。

(2)这两个钩子函数要注意的是:
  • 只有组件被 keep-alive 包裹时,这两个生命周期函数才会被调用,如果作为正常组件使用,是不会被调用的。
  • 即使组件被 keep-alive 包裹,如果使用 exclude 排除之后,,这两个钩子依然不会被调用。

(3)上面样例中我们在子组件内部的钩子函数中输出了一些信息,当我们打开页面,先切换到标签 2 再切回标签 1,控制台输出如下:

3,选择性地缓存部分组件

(1)有时我们并不需要将 <keep-alive> 内的所有组件都进行缓存,<keep-alive> 提供了如下两个属性来实现这个需求:
  • include:只有匹配的组件会被缓存(支持字符串或正则表达)
  • exclude:任何匹配的组件都不会被缓存(支持字符串或正则表达)

(2)使用样例
  • 只缓存 name child1 的组件:
<keep-alive include="child1">
  <component :is="currentView"></component>
</keep-alive>

  • 不缓存 name child1 的组件:
<keep-alive exclude="child1">
  <component :is="currentView"></component>
</keep-alive>

  • 只缓存 name child1 child2 的组件:
<keep-alive include ="child1,child2">
  <component :is="currentView"></component>
</keep-alive>

  • 只缓存以 child 开头的组件(使用正则表达式,需使用 v-bind):
<keep-alive :include="/^child.*/">
  <component :is="currentView"></component>
</keep-alive>

  • 也可以动态绑定需要缓存的组件:
<keep-alive :include="includedComponents">
  <component :is="currentView"></component>
</keep-alive>
评论0