各位看官别急,今天了解的是Vue中内置组件KeepAlive,这也是前端面试中性能优化中的重难点
曾经作为一名安卓用户,我习惯了杀后台,因为后台占用了手机的内存资源。后面我姐给我一台苹果手机后,我也习惯于杀后台,直到有一天有人跟我说苹果不需要杀后台。
为啥IOS系统不要杀后台?难不成内藏玄鸡???
然后我就知道了原来是IOS有一个墓碑机制,那啥是墓碑机制呢?
iOS的墓碑机制并不是进入后台就把app杀掉,而是进入后台后,会有一个缓冲时间给app做background处理准备进入休眠,缓冲时间之后app的所有未注册的动作都将被禁止,iOS自己会根据情况允许你适时的回调,这就是墓碑。当下次app进入前台时,系统会从内存中读取上次缓存的app状态,甚至可以做到连interval都停住的状态。
没有用到KeepAlive的两个组件,当刷新页面时数据丢失。
用了KeepAlive的两个组件,当切换组件实例时不会丢失数据
在开发过程中,我们难免会碰到这样一种情况。默认情况下,一个组件实例在被替换掉后会被销毁。这会导致它丢失其中所有已变化的状态——当这个组件再一次被显示时,会创建一个只带有初始状态的新实例。
而在我们实际使用中,例如抖音刷个视频,如果有人给你发消息或者私信你,你去点击消息页面并且回复了他,这就切换了组件,然后你跳回首页刷视频给你刷新了页面,你发现你正在看的视频没了,这肯定是不行的。而且对于性能消耗来说,重新加载了资源肯定是很浪费资源的。如果说这时候能有一个墓碑机制去冻结我们切换页面的组件,等我们再返回时去获取上一次的缓存而不用重新加载资源。
Vue中的内置了[KeepAlive组件](KeepAlive | Vue.js (vuejs.org))做了这样的事情。
KeepAlive
KeepAlive
是 Vue.js 提供的一个内置组件,用于缓存动态组件,以提高应用性能。通过将组件包裹在 KeepAlive
组件中,Vue 可以在组件被切换时保持其状态,并避免重新渲染。KeepAlive
主要用于带有频繁切换的视图组件,如标签页或动态路由。
Props
KeepAlive
组件提供了一些有用的 props,可以进一步控制组件的缓存行为:
include
: 一个字符串或正则表达式,匹配的组件会被缓存。包括在内的。exclude
: 一个字符串或正则表达式,匹配的组件不会被缓存。排除在外的。max
: 一个数字,指定最多可以缓存多少组件实例。
注意点:在 Vue 中使用
KeepAlive
组件时,如果include
和exclude
属性同时存在,exclude
的优先级更高。这意味着,即使一个组件匹配include
规则,如果它也匹配exclude
规则,它仍然不会被缓存。 具体来说,如果一个组件的名字同时满足include
和exclude
规则,exclude
规则会覆盖include
规则,使得该组件不被缓存。
示例
<keep-alive include="viewA">
<component :is="currentView"></component>
</keep-alive>
<keep-alive :include="['viewA', 'viewB']">
<component :is="currentView"></component>
</keep-alive>
<keep-alive :exclude="/^view/">
<component :is="currentView"></component>
</keep-alive>
<keep-alive :max="10">
<component :is="currentView"></component>
</keep-alive>
在这些示例中,include
和 exclude
props 用于指定哪些组件应该被缓存,哪些不应该被缓存。max
prop 用于限制缓存的组件实例数量。
事件
KeepAlive
组件还提供了一些事件,可以在组件激活和停用时触发:
activated
: 当组件实例被激活时触发。deactivated
: 当组件实例被停用时触发。
示例
<template>
<div>
<keep-alive @activated="onActivated" @deactivated="onDeactivated">
<component :is="currentView"></component>
</keep-alive>
</div>
</template>
<script>
export default {
methods: {
onActivated() {
console.log('Component activated');
},
onDeactivated() {
console.log('Component deactivated');
}
}
}
</script>
通过使用这些事件,可以在组件状态变化时执行特定的逻辑。
KeepAlive的高级用法
与router结合使用
<template>
<div>
<router-view v-slot="{Component}">
<keep-alive :include="cachedComponents">
<component :is="Component" />
</keep-alive>
</router-view>
<div class="footer h-12">
<TabBar class="fixed bottom-0" />
</div>
</div>
</template>
<script setup lang="ts">
import TabBar from '@/views/layout/TabBar.vue'
import { computed } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter();
const cachedComponents = computed(() => {
return router.getRoutes()
.filter(route => route.meta.cache)
.map(route => route.name)
})
</script>
分析:
-
- 用v-slot写了一个具名插槽,挖了一个坑,去填充component里的内容
-
- include去写需要被缓存的组件
-
- tailwindcss原子化的css,class="footer h-12" 直接在类名内写样式
-
- router.getRoutes()获取所有路由信息,拿取route里meta中cache的值去判断这个组件是否要被缓存
在路由配置文件中加入meta对象中加入cache属性去判断是否要被缓存
{
path:'home',
name:'Home',
component: () => import('@/views/Home/Home.vue'),
meta:{
cache:true
}
},
{
path: 'discount',
name: 'Discount',
meta: {
cache: false
},
component: () => import('../views/Discount/Discount.vue')
},
这些就是我对于KeepAlive的理解,利用它能够性能优化,让本不需要重新加载的资源不重新加载,也防止丢失数据。 如果这对你有帮助,不妨点个免费的赞。