diff --git a/.changeset/thin-items-promise.md b/.changeset/thin-items-promise.md new file mode 100644 index 00000000..f71a5631 --- /dev/null +++ b/.changeset/thin-items-promise.md @@ -0,0 +1,5 @@ +--- +'@alita/plugins': patch +--- + +feat: keepalive support custom tabs diff --git a/examples/tabs/.umirc.ts b/examples/tabs/.umirc.ts index 22621efc..a257fac5 100644 --- a/examples/tabs/.umirc.ts +++ b/examples/tabs/.umirc.ts @@ -8,5 +8,7 @@ export default { mfsu: {}, antd: {}, hash: false, - tabsLayout: {}, + tabsLayout: { + hasCustomTabs: true, + }, }; diff --git a/examples/tabs/src/app.tsx b/examples/tabs/src/app.tsx index bb125c00..91a4fc9e 100644 --- a/examples/tabs/src/app.tsx +++ b/examples/tabs/src/app.tsx @@ -1,3 +1,8 @@ +import { message, Tabs } from 'antd'; +import React from 'react'; + +const { TabPane } = Tabs; + export const request = { prefix: '/api', method: 'get', @@ -27,3 +32,59 @@ export const tabsLayout = { // '/foo':'其他' // }}; // } + +export const getCustomTabs = () => { + return ({ + isKeep, + keepElements, + navigate, + dropByCacheKey, + local, + activeKey, + }: any) => { + return ( + + ); + }; +}; diff --git a/examples/tabs/src/layouts/index.tsx b/examples/tabs/src/layouts/index.tsx index 26deef8f..c8e54ab7 100644 --- a/examples/tabs/src/layouts/index.tsx +++ b/examples/tabs/src/layouts/index.tsx @@ -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; @@ -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(() => { @@ -72,6 +72,7 @@ const App: React.FC = () => { }} theme="dark" defaultSelectedKeys={[activeItem]} + selectedKeys={[activeItem]} mode="inline" items={items} /> diff --git a/packages/plugins/src/keepalive.ts b/packages/plugins/src/keepalive.ts index d308774e..054b717a 100644 --- a/packages/plugins/src/keepalive.ts +++ b/packages/plugins/src/keepalive.ts @@ -44,6 +44,7 @@ export default (api: AlitaApi) => { noPluginDir: true, content: Mustache.render(contextTpl, { hasTabsLayout: !!tabsLayout, + hasCustomTabs: !!tabsLayout?.hasCustomTabs, }), }); const runtimeTpl = readFileSync( diff --git a/packages/plugins/src/tabs-layout.ts b/packages/plugins/src/tabs-layout.ts index a60f1e8a..c27f2960 100644 --- a/packages/plugins/src/tabs-layout.ts +++ b/packages/plugins/src/tabs-layout.ts @@ -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']); }; diff --git a/packages/plugins/templates/keepalive/context.tpl b/packages/plugins/templates/keepalive/context.tpl index 9e32032f..cbef6b41 100644 --- a/packages/plugins/templates/keepalive/context.tpl +++ b/packages/plugins/templates/keepalive/context.tpl @@ -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; @@ -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(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}} + +{{/hasCustomTabs}} +{{^hasCustomTabs}} {{#hasTabsLayout}} -