我们不希望组件被重新渲染影响用户体验;或者处于性能考虑,避免多次重复渲染降低性能。而是希望组件可以缓存下来,维持当前的状态,这时候就可以用到keep-alive组件。
keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。keep-alive 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。
用法:
<keep-alive>
<component :is="view"></component>
</keep-alive>
<keep-alive :include="['a', 'b']">
<component :is="view"></component>
</keep-alive>
router-view 组件是一个 functional 组件,渲染路径匹配到的视图组件。router-view渲染的组件还可以内嵌自己的 router-view,根据嵌套路径,渲染嵌套组件。
<transition>
<keep-alive>
<router-view></router-view>
</keep-alive>
</transition>
// src/store/modules/tabbar.js
const state = {
cachedViews: []
}
const mutations = {
// 添加缓存页面
ADD_CACHED_VIEW: (state, view) => {
if (state.cachedViews.includes(view.name)) return
if (!view.meta.noCache) {
state.cachedViews.push(view.name)
}
},
// 删除缓存页面
DEL_CACHED_VIEW: (state, view) => {
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
state.cachedViews.splice(index, 1)
break
}
}
},
// 删除全部缓存页面
DEL_ALL_CACHED_VIEWS: state => {
state.cachedViews = []
}
}
const actions = {
addCachedView({ commit }, view) {
commit('ADD_CACHED_VIEW', view)
},
delCachedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_CACHED_VIEW', view)
resolve([...state.cachedViews])
})
},
delAllCachedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_CACHED_VIEWS')
resolve([...state.cachedViews])
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
watch: {
$route: {
handler(to, form = null) {
// 当路由改变时,检测该路由是否已经在打开的页面之中,如果不在,就添加进去
if (to.meta) {
this.pageCurrent = to.path
var index = this.pageList.findIndex(value => {
return value.name === to.path
})
if (index < 0) {
this.pageList.push({ name: to.path, label: to.meta.title, icon: to.meta.icon })
}
// 将需要缓存的页面放入状态管理器
const { name, meta } = this.$route
if (name && meta !== undefined && meta.noCache !== undefined && !meta.noCache) {
this.$store.dispatch('tabbar/addCachedView', this.$route)
}
}
},
immediate: true
}
}
removeTab(targetName) {
if (targetName === '/dashboard') return
const tabs = this.pageList
let activeName = this.pageCurrent
if (activeName === targetName) {
tabs.forEach((tab, index) => {
if (tab.name === targetName) {
const nextTab = tabs[index + 1] || tabs[index - 1]
if (nextTab) {
activeName = nextTab.name
}
}
})
}
this.pageCurrent = activeName
this.pageList = tabs.filter(tab => tab.name !== targetName)
// 将需要缓存页面从状态管理器中移除
this.$store.dispatch('tabbar/delCachedView', this.$route)
this.$router.push({ path: activeName })
}
<template>
<section class="app-main">
<!-- 有条件地对状态管理器的页面进行缓存v-->
<transition name="fade-transform" mode="out-in">
<keep-alive :include="this.$store.state.tabbar.cachedViews">
<router-view :key="key" />
</keep-alive>
</transition>
</section>
</template>
<script> export default { name: 'AppMain', computed: { // 页面缓存状态管理器 cachedViews() { return this.$store.state.tabbar.cachedViews }, key() { return this.$route.path } } } </script>
<style scoped> .app-main { /*50 = navbar */ min-height: calc(100vh - 50px); width: 100%; position: relative; overflow: hidden; } .fixed-header+.app-main { padding-top: 50px; } </style>
<style lang="scss"> // fix css style bug in open el-dialog .el-popup-parent--hidden { .fixed-header { padding-right: 15px; } } </style>
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/jpgzhu/article/details/121372033
内容来源于网络,如有侵权,请联系作者删除!