提交 | 用户 | age
|
2f6253
|
1 |
import type { TabContentProps } from './tab.data'; |
陈 |
2 |
import type { TabItem } from '/@/store/modules/tab'; |
|
3 |
import type { AppRouteRecordRaw } from '/@/router/types'; |
|
4 |
|
beb4c3
|
5 |
import { |
N |
6 |
defineComponent, |
|
7 |
watch, |
|
8 |
computed, |
|
9 |
// ref, |
|
10 |
unref, |
c7cfeb
|
11 |
// onMounted, |
31e271
|
12 |
toRaw, |
beb4c3
|
13 |
} from 'vue'; |
2f6253
|
14 |
import { Tabs } from 'ant-design-vue'; |
陈 |
15 |
import TabContent from './TabContent'; |
|
16 |
|
|
17 |
import { useGo } from '/@/hooks/web/usePage'; |
|
18 |
|
|
19 |
import { TabContentEnum } from './tab.data'; |
|
20 |
|
|
21 |
import { useRouter } from 'vue-router'; |
|
22 |
|
|
23 |
import { tabStore } from '/@/store/modules/tab'; |
|
24 |
import { closeTab } from './useTabDropdown'; |
|
25 |
import router from '/@/router'; |
f2bdf0
|
26 |
import { useTabs } from '/@/hooks/web/useTabs'; |
c7cfeb
|
27 |
// import { PageEnum } from '/@/enums/pageEnum'; |
f2bdf0
|
28 |
|
beb4c3
|
29 |
import './index.less'; |
6bffdb
|
30 |
import { userStore } from '/@/store/modules/user'; |
2f6253
|
31 |
export default defineComponent({ |
陈 |
32 |
name: 'MultiTabs', |
|
33 |
setup() { |
|
34 |
let isAddAffix = false; |
|
35 |
const go = useGo(); |
|
36 |
const { currentRoute } = useRouter(); |
c7cfeb
|
37 |
const { |
V |
38 |
// addTab, |
|
39 |
activeKeyRef, |
|
40 |
} = useTabs(); |
|
41 |
// onMounted(() => { |
|
42 |
// const route = unref(currentRoute); |
|
43 |
// addTab(unref(currentRoute).path as PageEnum, false, { |
|
44 |
// query: route.query, |
|
45 |
// params: route.params, |
|
46 |
// }); |
|
47 |
// }); |
f2bdf0
|
48 |
|
2f6253
|
49 |
// 当前激活tab |
beb4c3
|
50 |
// const activeKeyRef = ref<string>(''); |
N |
51 |
|
2f6253
|
52 |
// 当前tab列表 |
陈 |
53 |
const getTabsState = computed(() => { |
|
54 |
return tabStore.getTabsState; |
|
55 |
}); |
|
56 |
|
beb4c3
|
57 |
if (!isAddAffix) { |
N |
58 |
addAffixTabs(); |
|
59 |
isAddAffix = true; |
|
60 |
} |
|
61 |
|
2f6253
|
62 |
watch( |
陈 |
63 |
() => unref(currentRoute).path, |
6bffdb
|
64 |
() => { |
V |
65 |
if (!userStore.getTokenState) return; |
|
66 |
const { path: rPath, fullPath } = unref(currentRoute); |
|
67 |
if (activeKeyRef.value !== (fullPath || rPath)) { |
|
68 |
activeKeyRef.value = fullPath || rPath; |
2f6253
|
69 |
} |
f2bdf0
|
70 |
// 监听路由的话虽然可以,但是路由切换的时间会造成卡顿现象? |
V |
71 |
// 使用useTab的addTab的话,当用户手动调转,需要自行调用addTab |
6bffdb
|
72 |
tabStore.commitAddTab((unref(currentRoute) as unknown) as AppRouteRecordRaw); |
V |
73 |
|
|
74 |
// const { affix } = currentRoute.value.meta || {}; |
|
75 |
// if (affix) return; |
|
76 |
// const hasInTab = tabStore.getTabsState.some( |
|
77 |
// (item) => item.fullPath === currentRoute.value.fullPath |
|
78 |
// ); |
|
79 |
// if (!hasInTab) { |
|
80 |
// tabStore.commitAddTab((unref(currentRoute) as unknown) as AppRouteRecordRaw); |
|
81 |
// } |
2f6253
|
82 |
}, |
陈 |
83 |
{ |
6bffdb
|
84 |
// flush: 'post', |
2f6253
|
85 |
immediate: true, |
陈 |
86 |
} |
|
87 |
); |
beb4c3
|
88 |
|
2f6253
|
89 |
/** |
陈 |
90 |
* @description: 过滤所有固定路由 |
|
91 |
*/ |
|
92 |
function filterAffixTabs(routes: AppRouteRecordRaw[]) { |
|
93 |
const tabs: TabItem[] = []; |
|
94 |
routes && |
|
95 |
routes.forEach((route) => { |
|
96 |
if (route.meta && route.meta.affix) { |
31e271
|
97 |
tabs.push(toRaw(route) as TabItem); |
2f6253
|
98 |
} |
陈 |
99 |
}); |
|
100 |
return tabs; |
|
101 |
} |
beb4c3
|
102 |
|
2f6253
|
103 |
/** |
陈 |
104 |
* @description: 设置固定tabs |
|
105 |
*/ |
|
106 |
function addAffixTabs(): void { |
|
107 |
const affixTabs = filterAffixTabs((router.getRoutes() as unknown) as AppRouteRecordRaw[]); |
|
108 |
for (const tab of affixTabs) { |
|
109 |
tabStore.commitAddTab(tab); |
|
110 |
} |
|
111 |
} |
|
112 |
|
|
113 |
// tab切换 |
|
114 |
function handleChange(activeKey: any) { |
|
115 |
activeKeyRef.value = activeKey; |
|
116 |
go(activeKey, false); |
|
117 |
} |
beb4c3
|
118 |
|
2f6253
|
119 |
// 关闭当前ab |
陈 |
120 |
function handleEdit(targetKey: string) { |
|
121 |
// 新增操作隐藏,目前只使用删除操作 |
6bffdb
|
122 |
const index = unref(getTabsState).findIndex( |
V |
123 |
(item) => (item.fullPath || item.path) === targetKey |
|
124 |
); |
2f6253
|
125 |
index !== -1 && closeTab(unref(getTabsState)[index]); |
陈 |
126 |
} |
|
127 |
|
|
128 |
function renderQuick() { |
|
129 |
const tabContentProps: TabContentProps = { |
|
130 |
tabItem: (currentRoute as unknown) as AppRouteRecordRaw, |
|
131 |
type: TabContentEnum.EXTRA_TYPE, |
|
132 |
trigger: ['click', 'contextmenu'], |
|
133 |
}; |
|
134 |
return ( |
|
135 |
<span> |
31e271
|
136 |
<TabContent {...(tabContentProps as any)} /> |
2f6253
|
137 |
</span> |
陈 |
138 |
); |
|
139 |
} |
|
140 |
function renderTabs() { |
|
141 |
return unref(getTabsState).map((item: TabItem) => { |
6bffdb
|
142 |
const key = item.query ? item.fullPath : item.path; |
V |
143 |
|
2f6253
|
144 |
return ( |
6bffdb
|
145 |
<Tabs.TabPane key={key} closable={!(item && item.meta && item.meta.affix)}> |
2f6253
|
146 |
{{ |
陈 |
147 |
tab: () => <TabContent tabItem={item} />, |
|
148 |
}} |
|
149 |
</Tabs.TabPane> |
|
150 |
); |
|
151 |
}); |
|
152 |
} |
|
153 |
|
|
154 |
return () => { |
|
155 |
return ( |
|
156 |
<div class="multiple-tabs"> |
|
157 |
<Tabs |
|
158 |
type="editable-card" |
|
159 |
size="small" |
6e4005
|
160 |
animated={false} |
2f6253
|
161 |
hideAdd={true} |
770283
|
162 |
tabBarGutter={4} |
2f6253
|
163 |
activeKey={unref(activeKeyRef)} |
陈 |
164 |
onChange={handleChange} |
|
165 |
onEdit={handleEdit} |
|
166 |
> |
|
167 |
{{ |
|
168 |
default: () => renderTabs(), |
|
169 |
tabBarExtraContent: () => renderQuick(), |
|
170 |
}} |
|
171 |
</Tabs> |
|
172 |
</div> |
|
173 |
); |
|
174 |
}; |
|
175 |
}, |
|
176 |
}); |