1- import { defineComponent , computed } from 'vue' ;
1+ import { defineComponent , computed , nextTick , onMounted , watch } from 'vue' ;
22import { storeToRefs } from 'pinia' ;
3- import { useRoute } from 'vue-router' ;
4- import { usePermissionStore , useSettingStore } from '@/store' ;
3+ import { useRoute , useRouter } from 'vue-router' ;
4+ import { usePermissionStore , useSettingStore , useTabsRouterStore } from '@/store' ;
55
6- import TDesignHeader from './components/Header.vue' ;
7- import TDesignBreadcrumb from './components/Breadcrumb.vue' ;
8- import TDesignFooter from './components/Footer.vue' ;
9- import TDesignSideNav from './components/SideNav' ;
10- import TDesignContent from './components/Content.vue' ;
6+ import LayoutHeader from './components/Header.vue' ;
7+ import LayoutBreadcrumb from './components/Breadcrumb.vue' ;
8+ import LayoutFooter from './components/Footer.vue' ;
9+ import LayoutSideNav from './components/SideNav' ;
10+ import LayoutContent from './components/Content.vue' ;
11+ import Setting from './setting.vue' ;
1112
1213import { prefix } from '@/config/global' ;
13- import TdesignSetting from './setting.vue' ;
14+
1415import '@/style/layout.less' ;
1516
1617const name = `${ prefix } -base-layout` ;
@@ -19,8 +20,10 @@ export default defineComponent({
1920 name,
2021 setup ( ) {
2122 const route = useRoute ( ) ;
23+ const router = useRouter ( ) ;
2224 const permissionStore = usePermissionStore ( ) ;
2325 const settingStore = useSettingStore ( ) ;
26+ const tabsRouterStore = useTabsRouterStore ( ) ;
2427 const { routers : menuRouters } = storeToRefs ( permissionStore ) ;
2528 const setting = storeToRefs ( settingStore ) ;
2629
@@ -57,10 +60,59 @@ export default defineComponent({
5760 return newMenuRouters ;
5861 } ) ;
5962
63+ const appendNewRoute = ( ) => {
64+ const {
65+ path,
66+ meta : { title } ,
67+ name,
68+ } = route ;
69+ tabsRouterStore . appendTabRouterList ( { path, title : title as string , name, isAlive : true } ) ;
70+ } ;
71+
72+ onMounted ( ( ) => {
73+ appendNewRoute ( ) ;
74+ } ) ;
75+
76+ watch (
77+ ( ) => route . path ,
78+ ( ) => {
79+ appendNewRoute ( ) ;
80+ } ,
81+ ) ;
82+
83+ const handleRemove = ( { value : path , index } ) => {
84+ const { tabRouters } = tabsRouterStore ;
85+ const nextRouter = tabRouters [ index + 1 ] || tabRouters [ index - 1 ] ;
86+
87+ tabsRouterStore . subtractCurrentTabRouter ( { path, routeIdx : index } ) ;
88+ if ( path === route . path ) {
89+ router . push ( nextRouter . path ) ;
90+ }
91+ } ;
92+ const handleChangeCurrentTab = ( path : string ) => {
93+ router . push ( path ) ;
94+ } ;
95+ const handleRefresh = ( currentPath : string , routeIdx : number ) => {
96+ tabsRouterStore . toggleTabRouterAlive ( routeIdx ) ;
97+ nextTick ( ( ) => {
98+ tabsRouterStore . toggleTabRouterAlive ( routeIdx ) ;
99+ router . replace ( { path : currentPath } ) ;
100+ } ) ;
101+ } ;
102+ const handleCloseAhead = ( path : string , routeIdx : number ) => {
103+ tabsRouterStore . subtractTabRouterAhead ( { path, routeIdx } ) ;
104+ } ;
105+ const handleCloseBehind = ( path : string , routeIdx : number ) => {
106+ tabsRouterStore . subtractTabRouterBehind ( { path, routeIdx } ) ;
107+ } ;
108+ const handleCloseOther = ( path : string , routeIdx : number ) => {
109+ tabsRouterStore . subtractTabRouterOther ( { path, routeIdx } ) ;
110+ } ;
111+
60112 const renderSidebar = ( ) => {
61113 return (
62114 settingStore . showSidebar && (
63- < TDesignSideNav
115+ < LayoutSideNav
64116 showLogo = { settingStore . showSidebarLogo }
65117 layout = { settingStore . layout }
66118 isFixed = { settingStore . isSidebarFixed }
@@ -75,7 +127,7 @@ export default defineComponent({
75127 const renderHeader = ( ) => {
76128 return (
77129 settingStore . showHeader && (
78- < TDesignHeader
130+ < LayoutHeader
79131 showLogo = { settingStore . showHeaderLogo }
80132 theme = { settingStore . displayMode }
81133 layout = { settingStore . layout }
@@ -90,18 +142,72 @@ export default defineComponent({
90142 const renderFooter = ( ) => {
91143 return (
92144 < t-footer class = { `${ prefix } -footer-layout` } >
93- < TDesignFooter />
145+ < LayoutFooter />
94146 </ t-footer >
95147 ) ;
96148 } ;
97149
98150 const renderContent = ( ) => {
99- const { showBreadcrumb, showFooter } = settingStore ;
151+ const { showBreadcrumb, showFooter, isUseTabsRouter } = settingStore ;
152+ const { tabRouters } = tabsRouterStore ;
100153 return (
101154 < t-layout class = { [ `${ prefix } -layout` ] } >
155+ { isUseTabsRouter && (
156+ < t-tabs
157+ theme = "card"
158+ class = { `${ prefix } -layout-tabs-nav` }
159+ value = { route . path }
160+ onChange = { handleChangeCurrentTab }
161+ style = { { maxWidth : '100%' , position : 'fixed' , overflow : 'visible' } }
162+ onRemove = { handleRemove }
163+ >
164+ { tabRouters . map ( ( router : any , idx : number ) => (
165+ < t-tab-panel
166+ value = { router . path }
167+ key = { `${ router . path } _${ idx } ` }
168+ label = {
169+ < t-dropdown
170+ trigger = "context-menu"
171+ minColumnWidth = { 128 }
172+ popupProps = { { overlayClassName : 'router-tabs-dropdown' } }
173+ v-slots = { {
174+ dropdown : ( ) => (
175+ < t-dropdown-menu >
176+ < t-dropdown-item onClick = { ( ) => handleRefresh ( router . path , idx ) } >
177+ < t-icon name = "refresh" />
178+ 刷新
179+ </ t-dropdown-item >
180+ { idx > 0 && (
181+ < t-dropdown-item onClick = { ( ) => handleCloseAhead ( router . path , idx ) } >
182+ < t-icon name = "arrow-left" />
183+ 关闭左侧
184+ </ t-dropdown-item >
185+ ) }
186+ { idx < tabRouters . length - 1 && (
187+ < t-dropdown-item onClick = { ( ) => handleCloseBehind ( router . path , idx ) } >
188+ < t-icon name = "arrow-right" />
189+ 关闭右侧
190+ </ t-dropdown-item >
191+ ) }
192+ < t-dropdown-item onClick = { ( ) => handleCloseOther ( router . path , idx ) } >
193+ < t-icon name = "close-circle" />
194+ 关闭其它
195+ </ t-dropdown-item >
196+ </ t-dropdown-menu >
197+ ) ,
198+ } }
199+ >
200+ { ! router . isHome ? router . title : < t-icon name = "home" /> }
201+ </ t-dropdown >
202+ }
203+ removable = { ! router . isHome }
204+ />
205+ ) ) }
206+ </ t-tabs >
207+ ) }
102208 < t-content class = { `${ prefix } -content-layout` } >
103- { showBreadcrumb && < TDesignBreadcrumb /> }
104- < TDesignContent />
209+ { showBreadcrumb && < LayoutBreadcrumb /> }
210+ < LayoutContent />
105211 </ t-content >
106212 { showFooter && renderFooter ( ) }
107213 </ t-layout >
@@ -134,7 +240,7 @@ export default defineComponent({
134240 < t-layout class = { this . mainLayoutCls } > { [ sidebar , content ] } </ t-layout >
135241 </ t-layout >
136242 ) }
137- < TdesignSetting />
243+ < Setting />
138244 </ div >
139245 ) ;
140246 } ,
0 commit comments