VUE built-in component - application of KeepAlive

Briefly

<KeepAlive> is a built-in component whose function is to cache removed component instances when dynamically switching between multiple components.
By default, a component instance is destroyed when it is replaced. This will cause it to lose any changed state in it - when the component is displayed again, a new instance will be created with only the initial state.
If we really want components to retain their state when they are "cut away". To solve this problem, we can wrap these components with <KeepAlive> built-in components to achieve the effect.

KeepAlive component

<KeepAlive> caches all internal component instances by default.

usage

Just wrap the component to be cached with <KeepAlive>.

<!-- 非活跃的组件将会被缓存! -->
<KeepAlive>
<!-- 组件 -->
  ...
</KeepAlive>

Component include and exclude attributes

<KeepAlive> will cache all internal component instances by default, but we can customize this behavior through include and exclude props. The value of both props can be a comma-separated string, a regular expression, or an array containing both types:

<!-- 以英文逗号分隔的字符串 -->
<KeepAlive include="a,b" exclude="c">
  <component :is="view" />
</KeepAlive>

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

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

The matching values ​​of the two properties will be matched according to the name option of the component , so if the component wants to be cached by KeepAlive conditionally, it must explicitly declare a name option.

max attribute

The max prop limits the maximum number of component instances that can be cached. <KeepAlive> behaves like an LRU cache when max is specified: if the number of cached instances is about to exceed the specified maximum number, the cached instance that has not been accessed for the longest time will be destroyed to make room for new ones.

The lifecycle of a cache instance

Cached components become inactive when unloaded and active when reloaded.
A persistent component can register the corresponding two state lifecycle hooks via onActivated() and onDeactivated():

<script setup>
import {
    
     onActivated, onDeactivated } from 'vue'

onActivated(() => {
    
    
  // 调用时机为首次挂载
  // 以及每次从缓存中被重新插入时
})

onDeactivated(() => {
    
    
  // 在从 DOM 上移除、进入缓存
  // 以及组件卸载时调用
})
</script>

example

form component

<template>
  <div class="container">
    <a-form
      :layout="formState.layout"
      :model="formState"
      v-bind="formItemLayout"
    >
      <a-form-item label="姓名">
        <a-input
          v-model:value="formState.fieldA"
          placeholder="input placeholder"
        />
      </a-form-item>
      <a-form-item label="职位">
        <a-input
          v-model:value="formState.fieldB"
          placeholder="input placeholder"
        />
      </a-form-item>
    </a-form>
  </div>
</template>
<script lang="ts" setup>
import {
      
      
  reactive,
  toRefs,
  onBeforeMount,
  onMounted,
  computed,
  onActivated,
  onDeactivated,
} from "vue";
const formState = reactive({
      
      
  layout: "horizontal",
  fieldA: "",
  fieldB: "",
});
const formItemLayout = computed(() => {
      
      
  const {
      
       layout } = formState;
  return layout === "horizontal"
    ? {
      
      
        labelCol: {
      
      
          span: 4,
        },
        wrapperCol: {
      
      
          span: 14,
        },
      }
    : {
      
      };
});
const buttonItemLayout = computed(() => {
      
      
  const {
      
       layout } = formState;
  return layout === "horizontal"
    ? {
      
      
        wrapperCol: {
      
      
          span: 14,
          offset: 4,
        },
      }
    : {
      
      };
});

onActivated(() => {
      
      
  // 调用时机为首次挂载
  // 以及每次从缓存中被重新插入时
  console.log(`
  // 调用时机为首次挂载
  // 以及每次从缓存中被重新插入时
  `);
});

onDeactivated(() => {
      
      
  console.log(
    `
    // 在从 DOM 上移除、进入缓存
  // 以及组件卸载时调用
    `
  );
});
</script>
<style lang="scss" scoped></style>

step bar component

<template>
  <div class="container">
    <div class="step__wrapper">
      <a-steps :current="step">
        <a-step>
          <template #title>第一步</template>
          <template #description>
            <span>这是第一步</span>
          </template>
        </a-step>

        <a-step title="第二步" description="这是第二步" />
        <a-step title="第三步" description="第三步" />
      </a-steps>
      <KeepAlive>
        <MyForm name="a" v-if="step === 0"> </MyForm>
        <MyForm name="b" v-else-if="step === 1"> </MyForm>
        <MyForm name="c" v-else-if="step === 2"> </MyForm>
      </KeepAlive>
      <div class="handler__button__box">
        <a-button class="button" v-show="step > 0" @click="step--">
          上一步</a-button
        >
        <a-button class="button" v-show="step < 2" @click="step++">
          下一步</a-button
        >
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import {
      
       reactive, ref, toRefs, onBeforeMount, onMounted, computed } from "vue";
import MyForm from "./MyForm.vue";
const step = ref<number>(0); //  当前步骤
</script>
<style lang="scss" scoped>
.container {
      
      
  height: 100px;
}
.step__wrapper {
      
      
  position: relative;
  margin: 0 100px;
  margin-top: 50px;
  height: 300px;
}
.handler__button__box {
      
      
  position: absolute;
  bottom: 0;
  width: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
  & .button:nth-child(2n) {
      
      
    margin-left: 8px;
  }
}
</style>

The component does not consider the data communication between parent and child components, and only demonstrates the effect of component caching.
insert image description here

epilogue

it's over.

Guess you like

Origin blog.csdn.net/qq_43231248/article/details/128674917