Vue 内置组件 keep-alive, 官方文档看不懂就看这个!

1,416 阅读2分钟

keep-alive 是什么

keep-alive 是 Vue 的内置组件,keep-alive 包裹的动态组件在切换的时候不会进行销毁,而是缓存到内存中并执行 deactivated 钩子函数

keep-alive 的作用

在动态组件切换的时候,保存组件的状态、防止多次渲染DOM、降低性能消耗 动态组件如果不用 keep-alive 包裹,相当于每次切换组件都会销毁、创建(反复销毁创建DOM),这样会导致组件里面的数据无法保存

举个栗子

aaa.vue

<template>
  <div id="aaa">
    <p>温情aaa</p>
  </div>
</template>

<script>
export default {
  name: 'aaa',
  activated() {
    console.log('进来');
  },
  deactivated() {
    console.log('离开');
  }
}
</script>

bbb.vue

<template>
  <div>
    <p>温情bbb --- <span>{{ msg }}</span></p>
    <input type="text" v-model="msg">
  </div>
</template>

<script>
export default {
  name: 'bbb',
  data() {
      return {
          msg: ''
      }
  },
  mounted() {
    console.log('组件bbb创建完成');
  },
  destroyed() {
    console.log('组件bbb已被销毁');
  }
}
</script>

ccc.vue

<template>
  <div id="ccc">
      <p>温情ccc --- <span>{{ msg }}</span></p>
      <input type="text" v-model="msg">
  </div>
</template>

<script>
export default {
    name: 'ccc',
    data() {
        return {
            msg: ''
        }
    },
    mounted() {
      console.log('组件ccc创建完成');
    },
    destroyed() {
      console.log('组件ccc已被销毁');
    }
}
</script>

home.vue

<template>
  <div class="home">
    <button @click="show(index)" :class="{active:currentIndex == index}" v-for="(item, index) in arr" :key="item.btnName">{{ item.btnName }}</button>
    <keep-alive>
      <component :is="arr[currentIndex].componentName"></component>
    </keep-alive>
  </div>
</template>
<script>
import comA from '@/components/aaa.vue'
import comB from '@/components/bbb.vue'
import comC from '@/components/ccc.vue'

export default {
  name: 'Home',
  components: {
    comA, comB, comC
  },
  data() {
    return {
      arr: [
        {btnName: '按钮1', componentName: 'comA'},
        {btnName: '按钮2', componentName: 'comB'},
        {btnName: '按钮3', componentName: 'comC'},
      ],
      currentIndex: 0
    }
  },
  methods: {
    show(index) {
      this.currentIndex = index;
    }
  }
}
</script>

遍历了 A、B、C组件,点击动态切换组件,这时使用 keep-alive 包裹了动态组件,看看效果

在这里插入图片描述

此时使用了 keep-alive 进行包裹, 切换时不会销毁组件,也不会多次创建渲染组件,而是保存我们组件的状态,那如果把 keep-alive 注释掉,会是什么效果呢?

在这里插入图片描述

显而易见,没有了 keep-alive 的包裹,组件的切换会频繁的销毁、创建 DOM,而且不会保存组件里面的状态值

kepp-alive 生命周期钩子函数

对于 keep-alive 组件来说,它拥有两个独有的生命周期钩子函数,分别是 activated 和 deactivated activated: 进入组件的时候触发 deactiveted: 离开组件的时候触发

aaa.vue

export default {
   activated() {
	  console.log('进来');
   },
   deactivated() {
	  console.log('离开');
   }
}

在这里插入图片描述

keep-alive 的 props

  • include: 字符串或正则表达式 - 只有名称匹配的组件会被渲染
  • exclude: 字符串或正则表达式 - 名称匹配的组件都不会被渲染
  • max: 数字 - 设置最多可以缓存多少组件实例,一旦到达了这个数字,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉
<!-- 逗号分隔字符串 -->
<keep-alive include="a, b, c">
  <component :is="view"></component>
</keep-alive>

<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b|c/">
  <component :is="view"></component>
</keep-alive>

<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b', 'c']">
  <component :is="view"></component>
</keep-alive>

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