feat(plugin-layout): 多页签支持配置title (#174)

* feat(plugin-layout): 多页签支持配置title

* feat: 更改参数名 & 关闭页面清数据

* docs: 更新文档

* docs: 更新文档
This commit is contained in:
听海 2023-03-13 20:28:03 +08:00 committed by GitHub
parent 4ec95149e9
commit f1324979f9
12 changed files with 78 additions and 30 deletions

View File

@ -313,7 +313,7 @@ export const layout = (layoutConfig, { initialState }) => ({
比如: 比如:
```js ```js
export const access = { export const layout = {
unAccessHandler({ to, next }) { unAccessHandler({ to, next }) {
const accesssIds = accessApi.getAccess(); const accesssIds = accessApi.getAccess();
if (to.path === '/404') { if (to.path === '/404') {
@ -343,7 +343,7 @@ export const access = {
比如: 比如:
```js ```js
export const access = { export const layout = {
noFoundHandler({ next }) { noFoundHandler({ next }) {
const accesssIds = accessApi.getAccess(); const accesssIds = accessApi.getAccess();
if (!accesssIds.includes('/404')) { if (!accesssIds.includes('/404')) {
@ -354,6 +354,30 @@ export const access = {
}; };
``` ```
## API
### useTabTitle
类型定义如下:
```ts
function useTabTitle(title: string | Ref<string>): void;
```
当使用多页签模式时,在页面中使用 `useTabTitle` 可以自定义页面标签:
```vue
<script setup>
import { useRoute, useTabTitle } from '@fesjs/fes';
const titleRef = useTabTitle(`详情-${route.params?.id}`);
//如果要更新
titleRef.value = "changed"
</script>
```
## 4.x 升级到 5.x ## 4.x 升级到 5.x
1. 个性化 layout 配置改为使用传入 navigation 1. 个性化 layout 配置改为使用传入 navigation

View File

@ -7,7 +7,7 @@ export default async function createHtmlWebpackConfig({ api, cwd, config, webpac
filename: '[name].html', filename: '[name].html',
...config.html, ...config.html,
templateParameters: { templateParameters: {
title: config.html?.title || api.config.title || 'Fes.js', title: api.config.title || config.html?.title || 'fes.js',
...resolveRuntimeEnv(publicPath), ...resolveRuntimeEnv(publicPath),
mountElementId: config.mountElementId, mountElementId: config.mountElementId,
}, },

View File

@ -75,7 +75,7 @@ export default (api) => {
api.addPluginExports(() => [ api.addPluginExports(() => [
{ {
specifiers: ['Page'], specifiers: ['Page', 'useTabTitle'],
source: join(namespace, 'index.js'), source: join(namespace, 'index.js'),
}, },
]); ]);

View File

@ -1 +1,2 @@
export { default as Page } from './views/page.vue'; export { default as Page } from './views/page.vue';
export { useTabTitle } from './useTitle';

View File

@ -0,0 +1,18 @@
import { reactive, ref } from 'vue';
import { useRoute } from '@@/core/coreExports';
const cache = reactive(new Map());
export const getTitle = (path) => cache.get(path);
export const deleteTitle = (patch) => cache.delete(patch);
export const useTabTitle = (title) => {
const route = useRoute();
const titleRef = ref(title);
const path = route.path;
cache.set(path, titleRef);
return titleRef;
};

View File

@ -31,6 +31,7 @@ import { FTabs, FTabPane, FDropdown } from '@fesjs/fes-design';
import { ReloadOutlined, MoreOutlined } from '@fesjs/fes-design/icon'; import { ReloadOutlined, MoreOutlined } from '@fesjs/fes-design/icon';
import { useRouter, useRoute } from '@@/core/coreExports'; import { useRouter, useRoute } from '@@/core/coreExports';
import { transTitle } from '../helpers/pluginLocale'; import { transTitle } from '../helpers/pluginLocale';
import { getTitle, deleteTitle } from '../useTitle';
import Page from './page.vue'; import Page from './page.vue';
let i = 0; let i = 0;
@ -52,17 +53,20 @@ export default {
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const createPage = (_route) => { const createPage = (_route) => {
const title = _route.meta.title; const computedTitle = computed(() => {
const customTitle = unref(getTitle(_route.path));
return customTitle ?? transTitle(_route.meta.title);
});
return { return {
path: _route.path, path: _route.path,
route: _route, route: _route,
name: _route.meta.name ?? _route.name, name: _route.meta.name ?? _route.name,
title: computed(() => transTitle(title)), title: computedTitle,
key: getKey(), key: getKey(),
}; };
}; };
const pageList = ref([createPage(route)]); const pageList = ref([createPage(router.currentRoute.value)]);
const actions = [ const actions = [
{ {
value: 'closeOtherPage', value: 'closeOtherPage',
@ -113,6 +117,7 @@ export default {
list.splice(index, 1); list.splice(index, 1);
pageList.value = list; pageList.value = list;
pageRef.value.removeKeepAlive(selectedPage.name); pageRef.value.removeKeepAlive(selectedPage.name);
deleteTitle(selectedPage.path);
}; };
const reloadPage = (path) => { const reloadPage = (path) => {
const selectedPage = findPage(path || unref(route.path)); const selectedPage = findPage(path || unref(route.path));

View File

@ -12,6 +12,8 @@ interface Menu {
export const Page: Component; export const Page: Component;
export function useTabTitle(title: string | Ref<string>): void;
interface LayoutRuntimeConfig { interface LayoutRuntimeConfig {
footer?: string; footer?: string;
theme?: 'dark' | 'light'; theme?: 'dark' | 'light';

View File

@ -24,7 +24,7 @@ export default function (api) {
path: 'fes.js', path: 'fes.js',
content: Mustache.render(fesTpl, { content: Mustache.render(fesTpl, {
enableTitle: api.config.title !== false, enableTitle: api.config.title !== false,
defaultTitle: api.config.title || '', defaultTitle: api.config.title || 'fes.js',
runtimePath, runtimePath,
rootElement: `#${api.config.mountElementId || 'app'}`, rootElement: `#${api.config.mountElementId || 'app'}`,
entryCode: ( entryCode: (

View File

@ -41,7 +41,7 @@ export default defineBuildConfig({
layout: { layout: {
title: 'Fes.js', title: 'Fes.js',
footer: 'Created by MumbleFE', footer: 'Created by MumbleFE',
multiTabs: false, multiTabs: true,
navigation: 'side', navigation: 'side',
theme: 'dark', theme: 'dark',
menus: [ menus: [

View File

@ -1,7 +1,5 @@
<template> <template>
<div class="page"> <div class="page">menuTest: {{ route.params }} <input style="border: 1px solid red" /></div>
menuTest: {{route.params}}
</div>
</template> </template>
<config> <config>
{ {
@ -9,17 +7,22 @@
} }
</config> </config>
<script> <script>
import { useRoute } from '@fesjs/fes'; import { useRoute, useTabTitle } from '@fesjs/fes';
export default { export default {
components: { components: {},
},
setup() { setup() {
const route = useRoute(); const route = useRoute();
const title = useTabTitle(`详情-${route.params?.id}`);
setTimeout(() => {
title.value = `详情-${route.params?.id}-changed`;
}, 1000);
return { return {
route route,
}; };
} },
}; };
</script> </script>

View File

@ -1,6 +1,11 @@
<template> <template>
<div class="page"> <div class="page">
menuTest-index menuTest-index
<div style="display: flex; flex-direction: column">
<router-link to="/menuTest/1">Go to 1</router-link>
<router-link to="/menuTest/2">Go to 2</router-link>
<router-link to="/menuTest/3">Go to 3</router-link>
</div>
</div> </div>
</template> </template>
<config> <config>
@ -10,12 +15,10 @@
</config> </config>
<script> <script>
export default { export default {
components: { components: {},
},
setup() { setup() {
return { return {};
}; },
}
}; };
</script> </script>

View File

@ -1,8 +0,0 @@
<template>
<div style="display: flex;flex-direction: column;">
<router-link to="/menuTest/1">Go to 1</router-link>
<router-link to="/menuTest/2">Go to 2</router-link>
<router-link to="/menuTest/3">Go to 3</router-link>
</div>
<router-view />
</template>