keep-alive
是 Vue 提供的一个内置组件,用于缓存动态组件。它可以保持动态组件的状态或避免重新渲染。keep-alive
对性能优化非常有帮助,特别是当你在多个视图之间切换时,可以避免不必要的重新渲染和初始化。
基本用法
要使用 keep-alive
,只需将它包裹在需要缓存的组件外面
<template>
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
</template>
<script setup>
import { ref } from 'vue'
//引入外部组件A 和 B
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
const currentComponent = ref('ComponentA')
</script>
配合 router-view
使用
<template>
<keep-alive>
<router-view></router-view>
</keep-alive>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
</script>
使用 include
和 exclude
属性
<template>
<keep-alive include="ComponentA,ComponentB">
<component :is="currentComponent"></component>
</keep-alive>
</template>
<script setup>
import { ref } from 'vue'
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
import ComponentC from './ComponentC.vue'
const currentComponent = ref('ComponentA')
</script>
使用 max
属性
<template>
<keep-alive :max="10">
<component :is="currentComponent"></component>
</keep-alive>
</template>
<script setup>
import { ref } from 'vue'
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
const currentComponent = ref('ComponentA')
</script>
使用场景
1. 表单填写页面
<template>
<keep-alive>
<FormComponent v-if="showForm"></FormComponent>
</keep-alive>
</template>
<script setup>
import { ref } from 'vue'
import FormComponent from './FormComponent.vue'
const showForm = ref(true)
</script>
2.页签(Tab)界面
<template>
<div>
<button @click="currentTab = 'Tab1'">Tab1</button>
<button @click="currentTab = 'Tab2'">Tab2</button>
<keep-alive>
<component :is="currentTab"></component>
</keep-alive>
</div>
</template>
<script setup>
import { ref } from 'vue'
import Tab1 from './Tab1.vue'
import Tab2 from './Tab2.vue'
const currentTab = ref('Tab1')
</script>
3. 数据加载较多的页面
<template>
<keep-alive>
<DataComponent v-if="showDataComponent"></DataComponent>
</keep-alive>
</template>
<script setup>
import { ref } from 'vue'
import DataComponent from './DataComponent.vue'
const showDataComponent = ref(true)
</script>
总结
keep-alive
是 Vue 中一个非常有用的优化工具,它能显著提升应用的性能,尤其在频繁切换的视图之间,能有效减少重新渲染和初始化的开销。在使用时,需要根据具体场景合理控制缓存的组件数量和缓存策略,以获得最佳的用户体验和性能表现。
示例代码
以下代码可以直接运行查看效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue Keep-Alive Example</title>
<script src="https://unpkg.com/vue@3.2.47/dist/vue.global.prod.js"></script>
</head>
<body>
<div id="app">
<button @click="currentComponent = 'ComponentA'">Show Component A</button>
<button @click="currentComponent = 'ComponentB'">Show Component B</button>
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
</div>
<script>
const ComponentA = {
template: `<div>Component A</div>`,
mounted () {
console.log('Component A mounted');
},
unmounted () {
console.log('Component A unmounted');
}
};
const ComponentB = {
template: `<div>Component B</div>`,
mounted () {
console.log('Component B mounted');
},
unmounted () {
console.log('Component B unmounted');
}
};
const app = Vue.createApp({
data () {
return {
currentComponent: 'ComponentA'
};
},
components: {
ComponentA,
ComponentB
}
});
app.mount('#app');
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue Keep-Alive with Router Example</title>
<script src="https://unpkg.com/vue@3.2.47/dist/vue.global.prod.js"></script>
<script src="https://unpkg.com/vue-router@4.1.6/dist/vue-router.global.prod.js"></script>
</head>
<body>
<div id="app">
<nav>
<router-link to="/page1">Page 1</router-link>
<router-link to="/page2">Page 2</router-link>
</nav>
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
<script>
const Page1 = {
template: `<div>Page 1</div>`,
mounted () {
console.log('Page 1 mounted');
},
unmounted () {
console.log('Page 1 unmounted');
}
};
const Page2 = {
template: `<div>Page 2</div>`,
mounted () {
console.log('Page 2 mounted');
},
unmounted () {
console.log('Page 2 unmounted');
}
};
const routes = [
{ path: '/page1', component: Page1 },
{ path: '/page2', component: Page2 }
];
const router = VueRouter.createRouter({
history: VueRouter.createWebHashHistory(),
routes
});
const app = Vue.createApp({});
app.use(router);
app.mount('#app');
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue Keep-Alive Include/Exclude Example</title>
<script src="https://unpkg.com/vue@3.2.47/dist/vue.global.prod.js"></script>
</head>
<body>
<div id="app">
<button @click="currentComponent = 'ComponentA'">Show Component A</button>
<button @click="currentComponent = 'ComponentB'">Show Component B</button>
<button @click="currentComponent = 'ComponentC'">Show Component C</button>
<keep-alive include="ComponentA,ComponentB">
<component :is="currentComponent"></component>
</keep-alive>
</div>
<script>
const ComponentA = {
template: `<div>Component A</div>`,
name: 'ComponentA',
mounted () {
console.log('Component A mounted');
},
unmounted () {
console.log('Component A unmounted');
}
};
const ComponentB = {
template: `<div>Component B</div>`,
name: 'ComponentB',
mounted () {
console.log('Component B mounted');
},
unmounted () {
console.log('Component B unmounted');
}
};
const ComponentC = {
template: `<div>Component C</div>`,
name: 'ComponentC',
mounted () {
console.log('Component C mounted');
},
unmounted () {
console.log('Component C unmounted');
}
};
const app = Vue.createApp({
data () {
return {
currentComponent: 'ComponentA'
};
},
components: {
ComponentA,
ComponentB,
ComponentC
}
});
app.mount('#app');
</script>
</body>
</html>