自学内容网 自学内容网

vue3学习记录-Teleport和KeepAlive

1.Teleport

Teleport组件在遮罩框很实用。

<template>
  <div class="hello">
  </div>
</template>
<style scoped lang="scss">
.hello {
  height: 200px;
  width: 90px;
  border: 1px solid #000;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
</style>

<script setup>
import InfiniteScroll from './components/HelloWorld.vue'
import { ref } from 'vue';



let page = 0
const fetchMoreItems = async () => {
  // 模拟API调用
  await new Promise(resolve => setTimeout(resolve, 1000))
  page++
  return Array.from({ length: 10 }, (_, i) => ({
    id: page * 10 + i,
    content: `Item ${page * 10 + i}`
  }))
}
</script>
<template>
  <div class="content">
    <Teleport :disabled="true" to="body">
      <InfiniteScroll>
      </InfiniteScroll>
    </Teleport>
  </div>
</template>
<style>
.content {
  position: relative;
  height: 50vh;
  width: 100%;
  background-color: aqua;
}
</style>

2.KeepAlive

<script setup>
import { ref } from 'vue';
import A from './components/A.vue';
import B from './components/B.vue';
const activeTab = ref('a'); // 用于控制选中的 tab

</script>
<template>
  <el-tabs v-model="activeTab">
    <el-tab-pane label="A" name="a">
      <component :is="A"></component>
    </el-tab-pane>
    <el-tab-pane label="Infinite Scroll" name="second">
      <component :is="B"></component>
    </el-tab-pane>
  </el-tabs>
</template>

//A.vue
<template>
<!-- elementui数字加减器 -->
  <el-input-number v-model="count" :min="1" :max="10" label="描述文字"></el-input-number>


</template>
<script setup>
import { ref } from 'vue' ;
const count = ref(1) ;
</script>

//B.vue
<template>
    <!-- elementui数字加减器 -->
    <el-radio-group v-model="radio1">
      <el-radio value="1" size="large">Option 1</el-radio>
      <el-radio value="2" size="large">Option 2</el-radio>
    </el-radio-group>
    </template>
    <script setup>
    import { ref } from 'vue' ;
    const radio1 = ref('1') ;
    </script>

本来以为这样的组件不是keepalive的,结果它竟然是keepalive的,但是我没有在代码里加入keepalive呢!!!应该是el-tabs处理过了的。用官方的例子吧那就

<script setup>
import { ref, shallowRef } from "vue";
import A from "./components/A.vue";
import B from "./components/B.vue";
const activeTab = ref("a");
const current = shallowRef(A);
</script>

<template>
  <div class="demo">
    <label><input type="radio" v-model="current" :value="A" /> A</label>
    <label><input type="radio" v-model="current" :value="B" /> B</label>
    <component :is="current"></component>
  </div>
</template>

这下就不是keppalive了。keepalive在vue2里也有,缓存组件状态的。

2.1 包含/排除

默认会缓存内部的所有组件实例,但我们可以通过 include 和 exclude prop 来定制该行为。这两个 prop 的值都可以是一个以英文逗号分隔的字符串、一个正则表达式,或是包含这两种类型的一个数组:

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

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

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

2.2 最大缓存实例数

我们可以通过传入 max prop 来限制可被缓存的最大组件实例数。 的行为在指定了 max 后类似一个 LRU 缓存:如果缓存的实例数量即将超过指定的那个最大数量,则最久没有被访问的缓存实例将被销毁,以便为新的实例腾出空间。

<KeepAlive :max="10">
  <component :is="activeComponent" />
</KeepAlive>

2.3 缓存实例的生命周期

vue3文档看到的。
当一个组件实例从 DOM 上移除但因为被 缓存而仍作为组件树的一部分时,它将变为不活跃状态而不是被卸载。当一个组件实例作为缓存树的一部分插入到 DOM 中时,它将重新被激活。
一个持续存在的组件可以通过 onActivated() 和 onDeactivated() 注册相应的两个状态的生命周期钩子:

<script setup>
import { shallowRef } from "vue";
import A from "./components/A.vue";
import B from "./components/B.vue";
const current = shallowRef(A);
</script>

<template>
  <div class="demo">
    <label><input type="radio" v-model="current" :value="A" /> A</label>
    <label><input type="radio" v-model="current" :value="B" /> B</label>
    <keep-alive>
      <component :is="current"></component>
    </keep-alive>
  </div>
</template>

<!-- ComponentA.vue -->
<script setup>
import { ref, onMounted, onActivated, onDeactivated } from 'vue';

const count = ref(0);

onMounted(() => {
  console.log('ComponentA mounted');
});

onActivated(() => {
  console.log('ComponentA activated');
});

onDeactivated(() => {
  console.log('ComponentA deactivated');
});

const increment = () => {
  count.value++;
};
</script>

<template>
  <div>
    <h2>组件 A</h2>
    <p>计数: {{ count }}</p>
    <button @click="increment">增加</button>
  </div>
</template>

<!-- ComponentB.vue -->
<script setup>
import { ref, onMounted, onActivated, onDeactivated } from 'vue';

const count = ref(0);

onMounted(() => {
  console.log('ComponentB mounted');
});

onActivated(() => {
  console.log('ComponentB activated');
});

onDeactivated(() => {
  console.log('ComponentB deactivated');
});

const increment = () => {
  count.value++;
};
</script>

<template>
  <div>
    <h2>组件 B</h2>
    <p>计数: {{ count }}</p>
    <button @click="increment">增加</button>
  </div>
</template>

1.当应用首次加载时,ComponentA 会被挂载,控制台会输出 “ComponentA mounted” 和 “ComponentA activated”。
2.当切换到 ComponentB 时:
ComponentA 会被停用,控制台输出 “ComponentA deactivated”。
ComponentB 会被挂载和激活,控制台输出 “ComponentB mounted” 和 “ComponentB activated”。
3.当再次切换回 ComponentA 时:
ComponentB 会被停用,控制台输出 “ComponentB deactivated”。
ComponentA 会被重新激活,控制台只输出 “ComponentA activated”(不会再次挂载)。
4.由于使用了 ,两个组件的状态(例如 count 值)会被保留,即使它们不在 DOM 中。
5.onActivated() 钩子在组件每次被插入到 DOM 时调用,无论是首次挂载还是从缓存中重新激活。
6.onDeactivated() 钩子在组件每次从 DOM 中移除时调用,但组件实例仍然保留在内存中。


原文地址:https://blog.csdn.net/qq_45030898/article/details/142883302

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!