Skip to content

Commit fbc013a

Browse files
refactor: layout index.tsx to index.vue
1 parent bd09cca commit fbc013a

File tree

8 files changed

+342
-293
lines changed

8 files changed

+342
-293
lines changed
+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<template>
2+
<t-layout :class="[`${prefix}-layout`]">
3+
<t-tabs
4+
v-if="isUseTabsRouter"
5+
theme="card"
6+
:class="`${prefix}-layout-tabs-nav`"
7+
:value="$route.path"
8+
@change="handleChangeCurrentTab"
9+
:style="{ position: 'sticky', top: 0, width: '100%' }"
10+
>
11+
<t-tab-panel
12+
v-for="(route, idx) in tabRouterList"
13+
:value="route.path"
14+
:key="`${route.path}_${idx}`"
15+
:removable="!route.isHome"
16+
@remove="() => this.handleRemove(route.path, idx)"
17+
>
18+
<template #label>
19+
<t-dropdown
20+
trigger="context-menu"
21+
:minColumnWidth="128"
22+
:popupProps="{ overlayClassName: 'route-tabs-dropdown' }"
23+
>
24+
<template v-if="!route.isHome">
25+
{{ route.title }}
26+
</template>
27+
<home-icon v-else />
28+
<template #dropdown>
29+
<t-dropdown-menu v-if="this.$route.path === route.path">
30+
<t-dropdown-item @click="() => this.handleRefresh(route.path, idx)">
31+
<refresh-icon />
32+
刷新
33+
</t-dropdown-item>
34+
<t-dropdown-item v-if="idx > 0" @lick="() => this.handleCloseAhead(route.path, idx)">
35+
<arrow-left-icon />
36+
关闭左侧
37+
</t-dropdown-item>
38+
<t-dropdown-item
39+
v-if="idx < this.tabRouterList.length - 1"
40+
@click="() => this.handleCloseBehind(route.path, idx)"
41+
>
42+
<arrow-right-icon />
43+
关闭右侧
44+
</t-dropdown-item>
45+
<t-dropdown-item @click="() => this.handleCloseOther(route.path, idx)">
46+
<close-circle-icon />
47+
关闭其它
48+
</t-dropdown-item>
49+
</t-dropdown-menu>
50+
</template>
51+
</t-dropdown>
52+
</template>
53+
</t-tab-panel>
54+
</t-tabs>
55+
<t-content :class="`${prefix}-content-layout`">
56+
<l-breadcrumb v-if="setting.showBreadcrumb" />
57+
<l-content />
58+
</t-content>
59+
<t-footer v-if="showFooter" :class="`${prefix}-footer-layout`">
60+
<l-footer />
61+
</t-footer>
62+
</t-layout>
63+
</template>
64+
65+
<script lang="ts">
66+
import Vue from 'vue';
67+
import { mapGetters } from 'vuex';
68+
import { RefreshIcon, ArrowLeftIcon, ArrowRightIcon, HomeIcon, CloseCircleIcon } from 'tdesign-icons-vue';
69+
70+
import LContent from './Content.vue';
71+
import LBreadcrumb from './Breadcrumb.vue';
72+
import LFooter from './Footer.vue';
73+
74+
import { prefix } from '@/config/global';
75+
import { SettingType } from '@/interface';
76+
77+
export default Vue.extend({
78+
name: 'LayoutContent',
79+
components: {
80+
LContent,
81+
LFooter,
82+
LBreadcrumb,
83+
RefreshIcon,
84+
ArrowLeftIcon,
85+
ArrowRightIcon,
86+
HomeIcon,
87+
CloseCircleIcon,
88+
},
89+
data() {
90+
return {
91+
prefix,
92+
};
93+
},
94+
computed: {
95+
...mapGetters({
96+
showFooter: 'setting/showFooter',
97+
mode: 'setting/mode',
98+
isUseTabsRouter: 'setting/isUseTabsRouter',
99+
menuRouters: 'permission/routers',
100+
tabRouterList: 'tabRouter/tabRouterList',
101+
}),
102+
setting(): SettingType {
103+
return this.$store.state.setting;
104+
},
105+
},
106+
methods: {
107+
handleRemove(path: string, routeIdx: number) {
108+
const nextRouter = this.tabRouterList[routeIdx + 1] || this.tabRouterList[routeIdx - 1];
109+
110+
this.$store.commit('tabRouter/subtractCurrentTabRouter', { path, routeIdx });
111+
if (path === this.$router.history?.current?.path) {
112+
this.$router.push(nextRouter.path);
113+
}
114+
},
115+
handleChangeCurrentTab(path: string) {
116+
this.$router.push(path);
117+
},
118+
handleRefresh(currentPath: string, routeIdx: number) {
119+
this.$store.commit('tabRouter/toggleTabRouterAlive', routeIdx);
120+
this.$nextTick(() => {
121+
this.$store.commit('tabRouter/toggleTabRouterAlive', routeIdx);
122+
this.$router.replace({ path: currentPath });
123+
});
124+
},
125+
handleCloseAhead(path: string, routeIdx: number) {
126+
this.$store.commit('tabRouter/subtractTabRouterAhead', { path, routeIdx });
127+
},
128+
handleCloseBehind(path: string, routeIdx: number) {
129+
this.$store.commit('tabRouter/subtractTabRouterBehind', { path, routeIdx });
130+
},
131+
handleCloseOther(path: string, routeIdx: number) {
132+
this.$store.commit('tabRouter/subtractTabRouterOther', { path, routeIdx });
133+
},
134+
},
135+
});
136+
</script>
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<template>
2+
<l-header
3+
v-if="showHeader"
4+
:showLogo="showHeaderLogo"
5+
:theme="mode"
6+
:layout="setting.layout"
7+
:isFixed="setting.isHeaderFixed"
8+
:menu="headerMenu"
9+
:isCompact="setting.isSidebarCompact"
10+
:maxLevel="setting.splitMenu ? 1 : 3"
11+
/>
12+
</template>
13+
14+
<script lang="ts">
15+
import Vue from 'vue';
16+
import { mapGetters } from 'vuex';
17+
import LHeader from './Header.vue';
18+
19+
import { SettingType } from '@/interface';
20+
21+
export default Vue.extend({
22+
name: 'LayoutHeader',
23+
components: {
24+
LHeader,
25+
},
26+
computed: {
27+
...mapGetters({
28+
showHeader: 'setting/showHeader',
29+
showHeaderLogo: 'setting/showHeaderLogo',
30+
mode: 'setting/mode',
31+
menuRouters: 'permission/routers',
32+
}),
33+
setting(): SettingType {
34+
return this.$store.state.setting;
35+
},
36+
headerMenu() {
37+
const { layout, splitMenu } = this.$store.state.setting;
38+
const { menuRouters } = this;
39+
if (layout === 'mix') {
40+
if (splitMenu) {
41+
return menuRouters.map((menu) => ({
42+
...menu,
43+
children: [],
44+
}));
45+
}
46+
return [];
47+
}
48+
return menuRouters;
49+
},
50+
},
51+
});
52+
</script>
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<template>
2+
<l-side-nav
3+
v-if="showSidebar"
4+
:showLogo="showSidebarLogo"
5+
:layout="setting.layout"
6+
:isFixed="setting.isSidebarFixed"
7+
:menu="sideMenu"
8+
:theme="mode"
9+
:isCompact="setting.isSidebarCompact"
10+
:maxLevel="setting.splitMenu ? 2 : 3"
11+
/>
12+
</template>
13+
14+
<script lang="ts">
15+
import Vue from 'vue';
16+
import { mapGetters } from 'vuex';
17+
import LSideNav from './SideNav.vue';
18+
19+
import { SettingType } from '@/interface';
20+
21+
export default Vue.extend({
22+
name: 'LayoutSidebar',
23+
components: {
24+
LSideNav,
25+
},
26+
computed: {
27+
...mapGetters({
28+
showSidebar: 'setting/showSidebar',
29+
showSidebarLogo: 'setting/showSidebarLogo',
30+
mode: 'setting/mode',
31+
menuRouters: 'permission/routers',
32+
}),
33+
setting(): SettingType {
34+
return this.$store.state.setting;
35+
},
36+
sideMenu() {
37+
const { layout, splitMenu } = this.$store.state.setting;
38+
let { menuRouters } = this;
39+
if (layout === 'mix' && splitMenu) {
40+
menuRouters.forEach((menu) => {
41+
if (this.$route.path.indexOf(menu.path) === 0) {
42+
menuRouters = menu.children.map((subMenu) => ({ ...subMenu, path: `${menu.path}/${subMenu.path}` }));
43+
}
44+
});
45+
}
46+
return menuRouters;
47+
},
48+
},
49+
});
50+
</script>
51+
<style lang="less" scoped></style>

0 commit comments

Comments
 (0)