Skip to content

Commit

Permalink
feat: keepalive support custom tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaohuoni committed Jun 20, 2022
1 parent 970a429 commit 3f2c7a6
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/thin-items-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@alita/plugins': patch
---

feat: keepalive support custom tabs
4 changes: 3 additions & 1 deletion examples/tabs/.umirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ export default {
mfsu: {},
antd: {},
hash: false,
tabsLayout: {},
tabsLayout: {
hasCustomTabs: true,
},
};
61 changes: 61 additions & 0 deletions examples/tabs/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { message, Tabs } from 'antd';
import React from 'react';

const { TabPane } = Tabs;

export const request = {
prefix: '/api',
method: 'get',
Expand Down Expand Up @@ -27,3 +32,59 @@ export const tabsLayout = {
// '/foo':'其他'
// }};
// }

export const getCustomTabs = () => {
return ({
isKeep,
keepElements,
navigate,
dropByCacheKey,
local,
activeKey,
}: any) => {
return (
<div className="rumtime-keep-alive-tabs-layout" hidden={!isKeep}>
<Tabs
hideAdd
onChange={(key: string) => {
navigate(key);
}}
activeKey={activeKey}
type="editable-card"
onEdit={(targetKey: string) => {
let newActiveKey = activeKey;
let lastIndex = -1;
const newPanel = Object.keys(keepElements.current);
for (let i = 0; i < newPanel.length; i++) {
if (newPanel[i] === targetKey) {
lastIndex = i - 1;
}
}
const newPanes = newPanel.filter((pane) => pane !== targetKey);
if (newPanes.length && newActiveKey === targetKey) {
if (lastIndex >= 0) {
newActiveKey = newPanes[lastIndex];
} else {
newActiveKey = newPanes[0];
}
}
if (lastIndex === -1 && targetKey === location.pathname) {
message.info('至少要保留一个窗口');
} else {
dropByCacheKey(targetKey);
if (newActiveKey !== location.pathname) {
navigate(newActiveKey);
}
}
}}
>
{Object.entries(keepElements.current).map(
([pathname, element]: any) => (
<TabPane tab={`${local[pathname] || pathname}`} key={pathname} />
),
)}
</Tabs>
</div>
);
};
};
5 changes: 3 additions & 2 deletions examples/tabs/src/layouts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import { useKeepOutlets, useLocation, useNavigate } from 'alita';
import type { MenuProps } from 'antd';
import { Layout, Menu } from 'antd';
import React, { useState, useEffect } from 'react';
import React, { useEffect, useState } from 'react';

const { Header, Content, Footer, Sider } = Layout;

Expand Down Expand Up @@ -38,7 +38,7 @@ const App: React.FC = () => {
const location = useLocation();

const [collapsed, setCollapsed] = useState(false);
const [activeItem ,setActiveItem] = useState(location.pathname);
const [activeItem, setActiveItem] = useState(location.pathname);

// 监听路由变化,激活路由对应的菜单
useEffect(() => {
Expand Down Expand Up @@ -72,6 +72,7 @@ const App: React.FC = () => {
}}
theme="dark"
defaultSelectedKeys={[activeItem]}
selectedKeys={[activeItem]}
mode="inline"
items={items}
/>
Expand Down
1 change: 1 addition & 0 deletions packages/plugins/src/keepalive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export default (api: AlitaApi) => {
noPluginDir: true,
content: Mustache.render(contextTpl, {
hasTabsLayout: !!tabsLayout,
hasCustomTabs: !!tabsLayout?.hasCustomTabs,
}),
});
const runtimeTpl = readFileSync(
Expand Down
9 changes: 7 additions & 2 deletions packages/plugins/src/tabs-layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ export default (api: AlitaApi) => {
key: 'tabsLayout',
config: {
schema(Joi) {
return Joi.alternatives(Joi.boolean(), Joi.object());
return Joi.alternatives(
Joi.boolean(),
Joi.object({
hasCustomTabs: Joi.boolean(),
}),
);
},
onChange: api.ConfigChangeType.regenerateTmpFiles,
},
enableBy: api.EnableBy.config,
});
// 注册runtime配置
api.addRuntimePluginKey(() => ['tabsLayout']);
api.addRuntimePluginKey(() => ['tabsLayout', 'getCustomTabs']);
};
37 changes: 31 additions & 6 deletions packages/plugins/templates/keepalive/context.tpl
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
import React, { useState } from 'react';
import { useOutlet, useLocation, matchPath, useNavigate } from 'react-router-dom'
{{#hasTabsLayout}}
{{^hasCustomTabs}}
{{#hasTabsLayout}}
import { Tabs, message } from 'antd';
{{/hasTabsLayout}}
{{/hasCustomTabs}}
{{#hasTabsLayout}}
import { getPluginManager } from '../core/plugin';
{{/hasTabsLayout}}
{{#hasCustomTabs}}
import { getCustomTabs } from '@/app';
{{/hasCustomTabs}}


export const KeepAliveContext = React.createContext({});

{{^hasCustomTabs}}
{{#hasTabsLayout}}
const { TabPane } = Tabs;
{{/hasTabsLayout}}
{{/hasCustomTabs}}

const isKeepPath = (aliveList: any[], path: string) => {
let isKeep = false;
Expand All @@ -34,14 +45,25 @@ export function useKeepOutlets() {
const runtime = getPluginManager().applyPlugins({ key: 'tabsLayout',type: 'modify', initialValue: {} });
const { local } = runtime;
{{/hasTabsLayout}}

const { cacheKeyMap, keepElements, keepalive, dropByCacheKey } = React.useContext<any>(KeepAliveContext);
const isKeep = isKeepPath(keepalive, location.pathname);
if (isKeep) {
keepElements.current[location.pathname] = element;
}
{{#hasCustomTabs}}
const CustomTabs = getCustomTabs();
const tabsProps = {
isKeep, keepElements, navigate, dropByCacheKey, local, activeKey: location.pathname
}
{{/hasCustomTabs}}
return <>
{{#hasCustomTabs}}
<CustomTabs {...tabsProps}/>
{{/hasCustomTabs}}
{{^hasCustomTabs}}
{{#hasTabsLayout}}
<div className="rumtime-keep-alive-tabs-layout" hidden={!isKeep} >
<div className="rumtime-keep-alive-tabs-layout" hidden={!isKeep} >
<Tabs hideAdd onChange={(key: string) => {
navigate(key);
}} activeKey={location.pathname} type="editable-card" onEdit={(targetKey: string,) => {
Expand All @@ -61,11 +83,13 @@ export function useKeepOutlets() {
newActiveKey = newPanes[0];
}
}
if (newActiveKey !== location.pathname) {
dropByCacheKey(targetKey);
navigate(newActiveKey);
} else if (lastIndex === -1 && targetKey === location.pathname) {
if (lastIndex === -1 && targetKey === location.pathname) {
message.info('至少要保留一个窗口');
} else {
dropByCacheKey(targetKey);
if (newActiveKey !== location.pathname) {
navigate(newActiveKey);
}
}
}}>
{Object.entries(keepElements.current).map(([pathname, element]: any) => (
Expand All @@ -74,6 +98,7 @@ export function useKeepOutlets() {
</Tabs>
</div>
{{/hasTabsLayout}}
{{/hasCustomTabs}}
{
Object.entries(keepElements.current).map(([pathname, children]: any) => (
<div key={`${pathname}:${cacheKeyMap[pathname] || '_'}`} style={ { height: '100%', width: '100%', position: 'relative', overflow: 'hidden auto' } } className="rumtime-keep-alive-layout" hidden={!matchPath(location.pathname, pathname)}>
Expand Down

0 comments on commit 3f2c7a6

Please sign in to comment.