Skip to content

Commit

Permalink
feat: 自定义keepAlive缓存支持无name缓存,支持不同路由同一组件复用时分别缓存
Browse files Browse the repository at this point in the history
  • Loading branch information
yuntian001 committed Aug 7, 2022
1 parent 43e7b93 commit 8cf313c
Show file tree
Hide file tree
Showing 61 changed files with 634 additions and 566 deletions.
27 changes: 13 additions & 14 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<!DOCTYPE html>
<html lang="en">

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>me-admin</title>
</head>

<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>me-admin</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>

<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>

</html>
</html>
6 changes: 3 additions & 3 deletions mock/apiDemo/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ const users = {
introduction: '我是一个管理员',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: '超级管理员',
username:'admin',
username: 'admin',
},
'editor-token': {
rules: ['edit', 'list'],
introduction: '我是一个编辑者',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: '编辑员工',
username:'editor',
username: 'editor',
},
'viewer': {
rules: ['list'],
introduction: '我是一个查询者',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: '查看员工',
username:'viewer',
username: 'viewer',
}
}
export default [
Expand Down
4 changes: 2 additions & 2 deletions mock/helper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export function success(data: any, msg = '操作成功') {
return { code: '200', data, msg }
return { code: '200', data, msg }
}

//code 401 代表token失效
Expand All @@ -18,5 +18,5 @@ export interface requestParams {
*
*/
export function getRequestToken({ headers }: requestParams): string | undefined {
return headers ? headers['auth-token']:'';
return headers ? headers['auth-token'] : '';
}
8 changes: 4 additions & 4 deletions mock/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ export function setupProdMockServer() {
import: 'default',
eager: true
});
let moduleArr:any[] = [];
Object.entries(modules).forEach(([key,module]:any)=>{
let moduleArr: any[] = [];
Object.entries(modules).forEach(([key, module]: any) => {
moduleArr = moduleArr.concat(module);

});
createProdMockServer([...moduleArr])
createProdMockServer([...moduleArr])
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@
"vite-svg-loader": "^3.4.0",
"vue-tsc": "^0.34.7"
}
}
}
20 changes: 10 additions & 10 deletions plugin/vueSetupExtend.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import xregexp from 'xregexp';
import { parse,compileScript } from '@vue/compiler-sfc';
import { parse, compileScript } from '@vue/compiler-sfc';
import MagicString from 'magic-string'
import { Plugin } from 'vite';
import { SFCDescriptor } from 'vue/compiler-sfc';
Expand All @@ -23,10 +23,10 @@ function getLangImport(content: string) {
if (useI18nParams.endsWith(']')) {
let arr = xregexp.matchRecursive(useI18nParams, '\\[', '\\]', 'g', {
escapeChar: '\\',
valueNames: [null,null,'value',null],
valueNames: [null, null, 'value', null],
});
let res = arr[arr.length - 1];
if(res && /\,\s*$/.test(useI18nParams.slice(0,res.start-1))){
if (res && /\,\s*$/.test(useI18nParams.slice(0, res.start - 1))) {
return '[' + res.value + ']';
}
}
Expand All @@ -35,12 +35,12 @@ function getLangImport(content: string) {
}


function getComponent(sfc: SFCDescriptor){
const sfcScriptBlock = compileScript(sfc,{id:'vueSetupExtendCompile'});
function getComponent(sfc: SFCDescriptor) {
const sfcScriptBlock = compileScript(sfc, { id: 'vueSetupExtendCompile' });
let components = [];
if(sfcScriptBlock.imports){
for( let key in sfcScriptBlock.imports){
if(/\.vue$/i.test(sfcScriptBlock.imports[key].source)){
if (sfcScriptBlock.imports) {
for (let key in sfcScriptBlock.imports) {
if (/\.vue$/i.test(sfcScriptBlock.imports[key].source)) {
components.push(key);
}
}
Expand All @@ -49,7 +49,7 @@ function getComponent(sfc: SFCDescriptor){
}


export function supportScript(code: string, options:ExtendOptions) {
export function supportScript(code: string, options: ExtendOptions) {
let s: MagicString | undefined
const str = () => s || (s = new MagicString(code))
const { descriptor } = parse(code);
Expand All @@ -65,7 +65,7 @@ export function supportScript(code: string, options:ExtendOptions) {
attrs.langImport = `{{${langImport}}}`;
}
}
if(options.setComponents){
if (options.setComponents) {
const components = getComponent(descriptor);
if (components.length) {
attrs.components = `{{{${components}}}}`;
Expand Down
6 changes: 3 additions & 3 deletions src/api/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ export interface UserInfoResult {
name: string,//名称
username: string//用户名
}
export function userInfoApi<T extends true | undefined>(returnAxios?:T) {
return request<UserInfoResult,[],T>(() => ({
export function userInfoApi<T extends true | undefined>(returnAxios?: T) {
return request<UserInfoResult, [], T>(() => ({
url: api.userInfo,
method: 'get'
}),{noLoading:true},returnAxios);
}), { noLoading: true }, returnAxios);
}
6 changes: 3 additions & 3 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import meKeepAlive from '@/components/meKeepAlive';
import clickOutside from "@/directive/clickOutside";
export const app = createApp(App);
export async function bootscrapt() {
app.component('sidebarItem',sidebarItem);
app.component('meKeepAlive',meKeepAlive);
app.directive('ClickOutside',clickOutside)
app.component('sidebarItem', sidebarItem);
app.component('meKeepAlive', meKeepAlive);
app.directive('ClickOutside', clickOutside)
await Promise.allSettled(mitter.emit(event.ready, app));
app.mount('#app');
}
6 changes: 3 additions & 3 deletions src/app.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<el-config-provider :locale="settingStore.elLocale" :size="settingStore.size" >
<router-view v-slot="{ Component, route }">
<me-component :is="Component"></me-component>
<el-config-provider :locale="settingStore.elLocale" :size="settingStore.size">
<router-view v-slot="{ Component }">
<me-component :is="Component" doneProgress></me-component>
</router-view>
</el-config-provider>
</template>
Expand Down
27 changes: 18 additions & 9 deletions src/components/meComponent.vue
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
<template>
<me-keep-alive v-if="keepAlive" v-bind="keepAlive">
<component :is="componentIs" :key="$route.fullPath" v-bind="$attrs"></component>
<component :is="componentIs" :key="key" v-bind="attrs"></component>
</me-keep-alive>
<component v-else :is="componentIs" :key="componentKey" v-bind="$attrs"></component>
<component v-else :is="componentIs" :key="key" v-bind="attrs"></component>
</template>
<script setup lang="ts">
<script setup lang="ts" name="meCompnent" inheritAttrs="{{false}}">
import { PropType, Ref } from 'vue';
import { MeKeepAliveProps } from './meKeepAlive';
import { useGetLoadMessagePromison } from '@/locales/i18n';
const route = useRoute();
const getLoadMessagePromison = useGetLoadMessagePromison();
import { useLoadMessages } from '@/locales/i18n';
import nProgress from 'nprogress';
const loadMessages = useLoadMessages();
const props = defineProps({
is: {
required: true,
},
keepAlive: Object as PropType<MeKeepAliveProps>,
componentKey: String,
componentKey: [Number, String, Symbol],
doneProgress: Boolean,
});
let componentIs: Ref<any> = ref(undefined);
const componentIs: Ref<any> = ref(undefined);
const key = ref(props.componentKey);
const current = getCurrentInstance();
const attrs = ref(current?.proxy?.$attrs);
watch(() => props.is, async (is) => {
if (is) {
await Promise.allSettled(getLoadMessagePromison(is as any));//自动加载语言包
await Promise.allSettled(loadMessages(is as any, false));//自动加载语言包
componentIs.value = is;
key.value = props.componentKey;
attrs.value = current?.proxy?.$attrs;
}
if (props.doneProgress) {
nProgress.done();
}
}, { immediate: true })
</script>
Expand Down
4 changes: 2 additions & 2 deletions src/components/meDarkSwitch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const settingStore = useSettingStore();
.#{$namespace}-switch {
.#{$namespace}-switch__core {
border-color: getCssVar('switch-off', 'color')!important;
background-color: getCssVar('switch-off', 'color')!important;
border-color: getCssVar('switch-off', 'color') !important;
background-color: getCssVar('switch-off', 'color') !important;
.#{$namespace}-switch__action {
background-color: getCssVar('bg', 'color');
Expand Down
26 changes: 13 additions & 13 deletions src/components/meKeepAlive/core/Suspense.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { queuePostFlushCb, SuspenseBoundary} from "vue"
import { queuePostFlushCb, SuspenseBoundary } from "vue"
import { isArray } from "@vue/shared"
export function queueEffectWithSuspense(
fn: Function | Function[],
suspense: SuspenseBoundary | null
): void {
if (suspense && suspense.pendingBranch) {
if (isArray(fn)) {
suspense.effects.push(...fn)
} else {
suspense.effects.push(fn)
}
fn: Function | Function[],
suspense: SuspenseBoundary | null
): void {
if (suspense && suspense.pendingBranch) {
if (isArray(fn)) {
suspense.effects.push(...fn)
} else {
queuePostFlushCb(fn)
suspense.effects.push(fn)
}
} else {
queuePostFlushCb(fn)
}
}

export const isSuspense = (type: any): boolean => type.__isSuspense

export const isSuspense = (type: any): boolean => type.__isSuspense



2 changes: 1 addition & 1 deletion src/components/meKeepAlive/core/component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ConcreteComponent } from "vue";
import {isFunction} from '@vue/shared'
import { isFunction } from '@vue/shared'
export function getComponentName(
Component: ConcreteComponent,
includeInferred = true
Expand Down
6 changes: 3 additions & 3 deletions src/components/meKeepAlive/core/componentPublicInstance.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ComponentInternalInstance } from "vue"

export interface ComponentRenderContext {
[key: string]: any
_: ComponentInternalInstance
}
[key: string]: any
_: ComponentInternalInstance
}
76 changes: 46 additions & 30 deletions src/components/meKeepAlive/core/devtools.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,52 @@
import { number } from "@intlify/core-base"
import { ComponentInternalInstance, devtools } from "vue"
const enum DevtoolsHooks {
APP_INIT = 'app:init',
APP_UNMOUNT = 'app:unmount',
COMPONENT_UPDATED = 'component:updated',
COMPONENT_ADDED = 'component:added',
COMPONENT_REMOVED = 'component:removed',
COMPONENT_EMIT = 'component:emit',
PERFORMANCE_START = 'perf:start',
PERFORMANCE_END = 'perf:end'
}
APP_INIT = 'app:init',
APP_UNMOUNT = 'app:unmount',
COMPONENT_UPDATED = 'component:updated',
COMPONENT_ADDED = 'component:added',
COMPONENT_REMOVED = 'component:removed',
COMPONENT_EMIT = 'component:emit',
PERFORMANCE_START = 'perf:start',
PERFORMANCE_END = 'perf:end'
}
export const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook(
DevtoolsHooks.COMPONENT_ADDED
)
DevtoolsHooks.COMPONENT_ADDED
)

function createDevtoolsComponentHook(hook: DevtoolsHooks) {
return (component: ComponentInternalInstance) => {
emit(
hook,
component.appContext.app,
component.uid,
component.parent ? component.parent.uid : undefined,
component
)
}
function createDevtoolsComponentHook(hook: DevtoolsHooks) {
return (component: ComponentInternalInstance) => {
emit(
hook,
component.appContext.app,
component.uid,
component.parent ? component.parent.uid : undefined,
component
)
}
}

function emit(event: string, ...args: any[]) {
if (devtools) {
devtools.emit(event, ...args)
}
//TODO::因为拿不到devtoolsNotInstalled和buffer这里做特别处理
// else if (!devtoolsNotInstalled) {
// buffer.push({ event, args })
// }
}
function emit(event: string, ...args: any[]) {
// if (devtools) {
// return devtools.emit(event, ...args)
// } else if (!devtoolsNotInstalled) {
// buffer.push({ event, args })
// }
//TODO::因为拿不到devtoolsNotInstalled和buffer这里只在devtools Installed 成功后处理
if (devtools) {
return devtools.emit(event, ...args)
}
//TODO::因为拿不到devtoolsNotInstalled和buffer这里做特别处理
// const doEmit = (event: string,frequency:number,...args: any[])=>{
// if (devtools) {
// return devtools.emit(event, ...args)
// }
// if(frequency > 3){
// return console.warn('devtools is Not installed');
// }
// setTimeout(() => {
// doEmit(event,frequency++,...args);
// }, 1000);
// }
// doEmit(event,1,args);
}
Loading

0 comments on commit 8cf313c

Please sign in to comment.