新增:增加多页签模式下配置是否缓存页面的功能;:star: #154
feat: add the function to configure whether to cache pages in multi tab mode;
| | |
| | | |
| | | function matches (pattern, name) { |
| | | if (Array.isArray(pattern)) { |
| | | return pattern.indexOf(name) > -1 |
| | | if (pattern.indexOf(name) > -1) { |
| | | return true |
| | | } else { |
| | | for (let item of pattern) { |
| | | if (isRegExp(item) && item.test(name)) { |
| | | return true |
| | | } |
| | | } |
| | | return false |
| | | } |
| | | } else if (typeof pattern === 'string') { |
| | | return pattern.split(',').indexOf(name) > -1 |
| | | } else if (isRegExp(pattern)) { |
| | |
| | | |
| | | function getComponentName (opts) { |
| | | return opts && (opts.Ctor.options.name || opts.tag) |
| | | } |
| | | |
| | | function getComponentKey (vnode) { |
| | | const {componentOptions, key} = vnode |
| | | return key == null |
| | | ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '') |
| | | : key + componentOptions.Ctor.cid |
| | | } |
| | | |
| | | function getFirstComponentChild (children) { |
| | |
| | | const cachedNode = cache[key] |
| | | if (cachedNode) { |
| | | const name = getComponentName(cachedNode.componentOptions) |
| | | if (name && !filter(name)) { |
| | | const componentKey = getComponentKey(cachedNode) |
| | | if (name && !filter(name, componentKey)) { |
| | | pruneCacheEntry(cache, key, keys, _vnode) |
| | | } |
| | | } |
| | |
| | | props: { |
| | | include: patternTypes, |
| | | exclude: patternTypes, |
| | | excludeKeys: patternTypes, |
| | | max: [String, Number], |
| | | clearCaches: Array |
| | | }, |
| | |
| | | |
| | | mounted () { |
| | | this.$watch('include', val => { |
| | | pruneCache(this, name => matches(val, name)) |
| | | pruneCache(this, (name) => matches(val, name)) |
| | | }) |
| | | this.$watch('exclude', val => { |
| | | pruneCache(this, name => !matches(val, name)) |
| | | pruneCache(this, (name) => !matches(val, name)) |
| | | }) |
| | | this.$watch('excludeKeys', val => { |
| | | pruneCache(this, (name, key) => !matches(val, key)) |
| | | }) |
| | | }, |
| | | |
| | |
| | | if (componentOptions) { |
| | | // check pattern |
| | | const name = getComponentName(componentOptions) |
| | | const { include, exclude } = this |
| | | const componentKey = getComponentKey(vnode) |
| | | const { include, exclude, excludeKeys } = this |
| | | if ( |
| | | // not included |
| | | (include && (!name || !matches(include, name))) || |
| | | // excluded |
| | | (exclude && name && matches(exclude, name)) |
| | | (exclude && name && matches(exclude, name)) || |
| | | (excludeKeys && componentKey && matches(excludeKeys, componentKey)) |
| | | ) { |
| | | return vnode |
| | | } |
| | |
| | | pageWidth: 'fixed', //内容区域宽度,fixed:固定宽度,fluid:流式宽度 |
| | | weekMode: false, //色弱模式,true:开启,false:不开启 |
| | | multiPage: false, //多页签模式,true:开启,false:不开启 |
| | | cachePage: true, //是否缓存页面数据,仅多页签模式下生效,true 缓存, false 不缓存 |
| | | hideSetting: false, //隐藏设置抽屉,true:隐藏,false:不隐藏 |
| | | systemName: 'Vue Antd Admin', //系统名称 |
| | | copyright: '2018 ICZER 工作室出品', //copyright |
| | |
| | | /> |
| | | <div :class="['tabs-view-content', layout, pageWidth]" :style="`margin-top: ${multiPage ? -24 : 0}px`"> |
| | | <page-toggle-transition :disabled="animate.disabled" :animate="animate.name" :direction="animate.direction"> |
| | | <a-keep-alive v-if="multiPage" v-model="clearCaches"> |
| | | <a-keep-alive :exclude-keys="excludeKeys" v-if="multiPage && cachePage" v-model="clearCaches"> |
| | | <router-view v-if="!refreshing" ref="tabContent" :key="$route.fullPath" /> |
| | | </a-keep-alive> |
| | | <router-view v-else /> |
| | | <router-view ref="tabContent" v-else-if="!refreshing" /> |
| | | </page-toggle-transition> |
| | | </div> |
| | | </admin-layout> |
| | |
| | | pageList: [], |
| | | activePage: '', |
| | | menuVisible: false, |
| | | refreshing: false |
| | | refreshing: false, |
| | | excludeKeys: [] |
| | | } |
| | | }, |
| | | computed: { |
| | | ...mapState('setting', ['multiPage', 'animate', 'layout', 'pageWidth']), |
| | | ...mapState('setting', ['multiPage', 'cachePage', 'animate', 'layout', 'pageWidth']), |
| | | menuItemList() { |
| | | return [ |
| | | { key: '1', icon: 'vertical-right', text: this.$t('closeLeft') }, |
| | |
| | | } |
| | | }, |
| | | created () { |
| | | this.loadCacheConfig(this.$router?.options?.routes) |
| | | this.loadCachedTabs() |
| | | const route = this.$route |
| | | if (this.pageList.findIndex(item => item.fullPath === route.fullPath) === -1) { |
| | |
| | | this.correctPageMinHeight(this.tabsOffset) |
| | | }, |
| | | watch: { |
| | | '$router.options.routes': function (val) { |
| | | this.excludeKeys = [] |
| | | this.loadCacheConfig(val) |
| | | }, |
| | | '$route': function (newRoute) { |
| | | this.activePage = newRoute.fullPath |
| | | if (!this.multiPage) { |
| | |
| | | } |
| | | } |
| | | }, |
| | | loadCacheConfig(routes, pCache = true) { |
| | | routes.forEach(item => { |
| | | const cacheAble = item.meta?.page?.cacheAble ?? pCache ?? true |
| | | if (!cacheAble) { |
| | | this.excludeKeys.push(new RegExp(`${item.fullPath}\\d+$`)) |
| | | } |
| | | if (item.children) { |
| | | this.loadCacheConfig(item.children, cacheAble) |
| | | } |
| | | }) |
| | | }, |
| | | ...mapMutations('setting', ['correctPageMinHeight']) |
| | | } |
| | | } |
| | |
| | | name: '表单页', |
| | | meta: { |
| | | icon: 'form', |
| | | page: { |
| | | cacheAble: false |
| | | } |
| | | }, |
| | | component: PageView, |
| | | children: [ |