fix: 修改TagsView样式问题

This commit is contained in:
戴业伟 2024-02-05 11:07:48 +08:00
parent 6fff76e3f8
commit 58337f771e

View File

@ -2,8 +2,8 @@
<div
class="box-border tabs-view"
:class="{
'tabs-view-fix': state.multiTabsSetting.fixed,
'tabs-view-fixed-header': state.isMultiHeaderFixed,
'tabs-view-fix': multiTabsSetting.fixed,
'tabs-view-fixed-header': isMultiHeaderFixed,
'tabs-view-default-background': getDarkTheme === false,
'tabs-view-dark-background': getDarkTheme === true,
}"
@ -13,11 +13,11 @@
<div
ref="navWrap"
class="tabs-card"
:class="{ 'tabs-card-scrollable': state.scrollable }"
:class="{ 'tabs-card-scrollable': scrollable }"
>
<span
class="tabs-card-prev"
:class="{ 'tabs-card-prev-hide': !state.scrollable }"
:class="{ 'tabs-card-prev-hide': !scrollable }"
@click="scrollPrev"
>
<n-icon size="16" color="#515a6e">
@ -26,7 +26,7 @@
</span>
<span
class="tabs-card-next"
:class="{ 'tabs-card-next-hide': !state.scrollable }"
:class="{ 'tabs-card-next-hide': !scrollable }"
@click="scrollNext"
>
<n-icon size="16" color="#515a6e">
@ -44,7 +44,7 @@
<div
:id="`tag${element.fullPath.split('/').join('\/')}`"
class="tabs-card-scroll-item"
:class="{ 'active-item': state.activeKey === element.fullPath }"
:class="{ 'active-item': activeKey === element.fullPath }"
@click.stop="goPage(element)"
@contextmenu="handleContextMenu($event, element)"
>
@ -76,9 +76,9 @@
</n-dropdown>
</div>
<n-dropdown
:show="state.showDropdown"
:x="state.dropdownX"
:y="state.dropdownY"
:show="showDropdown"
:x="dropdownX"
:y="dropdownY"
@clickoutside="onClickOutside"
placement="bottom-start"
@select="closeHandleSelect"
@ -88,13 +88,26 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts">
import {
defineComponent,
reactive,
computed,
ref,
toRefs,
provide,
watch,
onMounted,
nextTick,
} from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { storage } from '@/utils';
import { StorageEnum } from '@/enums/storageEnum';
import { useTabsViewStore } from '@/store/modules/tabsView';
import { useAsyncRouteStore } from '@/store/modules/asyncRoute';
import { RouteItem } from '@/store/modules/tabsView';
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
import { useMessage } from 'naive-ui';
import Draggable from 'vuedraggable';
import { PageEnum } from '@/enums/pageEnum';
import {
@ -107,42 +120,53 @@ import {
RightOutlined,
} from '@vicons/antd';
import { renderIcon } from '@/utils';
// import elementResizeDetectorMaker from "element-resize-detector";
// import elementResizeDetectorMaker from 'element-resize-detector';
import { useDesignSetting } from '@/hooks/setting/useDesignSetting';
import { useProjectSettingStore } from '@/store/modules/projectSetting';
import { useThemeVars } from 'naive-ui';
import { useGo } from '@/hooks/web/usePage';
import { StorageEnum } from '@/enums/storageEnum';
const props = defineProps({
export default defineComponent({
name: 'TabsView',
components: {
DownOutlined,
CloseOutlined,
LeftOutlined,
RightOutlined,
Draggable,
},
props: {
collapsed: {
type: Boolean,
},
});
const { getDarkTheme, getAppTheme } = useDesignSetting();
const { navMode, headerSetting, menuSetting, multiTabsSetting, isMobile } =
},
setup(props) {
const { getDarkTheme, getAppTheme } = useDesignSetting();
const { navMode, headerSetting, menuSetting, multiTabsSetting, isMobile } =
useProjectSetting();
const settingStore = useProjectSettingStore();
const settingStore = useProjectSettingStore();
const route = useRoute();
const router = useRouter();
const tabsViewStore = useTabsViewStore();
const asyncRouteStore = useAsyncRouteStore();
const navScroll: any = ref(null);
const navWrap: any = ref(null);
const isCurrent = ref(false);
const go = useGo();
const message = useMessage();
const route = useRoute();
const router = useRouter();
const tabsViewStore = useTabsViewStore();
const asyncRouteStore = useAsyncRouteStore();
const navScroll: any = ref(null);
const navWrap: any = ref(null);
const isCurrent = ref(false);
const go = useGo();
const themeVars = useThemeVars();
const themeVars = useThemeVars();
const getCardColor = computed(() => {
const getcardcolor = computed(() => {
return themeVars.value.cardColor;
});
});
const getBaseColor = computed(() => {
const getbasecolor = computed(() => {
return themeVars.value.textColor1;
});
});
const state = reactive({
const state = reactive({
activeKey: route.fullPath,
scrollable: false,
dropdownX: 0,
@ -150,15 +174,15 @@ const state = reactive({
showDropdown: false,
isMultiHeaderFixed: false,
multiTabsSetting: multiTabsSetting,
});
});
//
const getSimpleRoute = (route): RouteItem => {
//
const getSimpleRoute = (route): RouteItem => {
const { fullPath, hash, meta, name, params, path, query } = route;
return { fullPath, hash, meta, name, params, path, query };
};
};
const isMixMenuNoneSub = computed(() => {
const isMixMenuNoneSub = computed(() => {
const mixMenu = settingStore.menuSetting.mixMenu;
const currentRoute = useRoute();
if (navMode.value != 'horizontal-mix') return true;
@ -167,10 +191,10 @@ const isMixMenuNoneSub = computed(() => {
mixMenu &&
currentRoute.meta.isRoot
);
});
});
//
const getChangeStyle = computed(() => {
//
const getChangeStyle = computed(() => {
const { collapsed } = props;
const { minMenuWidth, menuWidth }: any = menuSetting.value;
const { fixed }: any = multiTabsSetting.value;
@ -191,10 +215,10 @@ const getChangeStyle = computed(() => {
left: lenNum,
width: `calc(100% - ${!fixed ? '0px' : lenNum})`,
};
});
});
//tags
const TabsMenuOptions = computed(() => {
//tags
const TabsMenuOptions = computed(() => {
const isDisabled = tabsList.value.length <= 1;
return [
{
@ -221,35 +245,35 @@ const TabsMenuOptions = computed(() => {
icon: renderIcon(MinusOutlined),
},
];
});
});
let cacheRoutes: RouteItem[] = [];
const simpleRoute = getSimpleRoute(route);
try {
let cacheRoutes: RouteItem[] = [];
const simpleRoute = getSimpleRoute(route);
try {
const routesStr = storage.get(StorageEnum.ZS_TABS_ROUTES) as
| string
| null
| undefined;
cacheRoutes = routesStr ? JSON.parse(routesStr) : [simpleRoute];
} catch (e) {
} catch (e) {
cacheRoutes = [simpleRoute];
}
}
// localStorage
const routes = router.getRoutes();
cacheRoutes.forEach((cacheRoute) => {
// localStorage
const routes = router.getRoutes();
cacheRoutes.forEach((cacheRoute) => {
const route = routes.find((route) => route.path === cacheRoute.path);
if (route) {
cacheRoute.meta = route.meta || cacheRoute.meta;
cacheRoute.name = (route.name || cacheRoute.name) as string;
}
});
});
//
tabsViewStore.initTabs(cacheRoutes);
//
tabsViewStore.initTabs(cacheRoutes);
//
function onScroll(e) {
//
function onScroll(e) {
let scrollTop =
e.target.scrollTop ||
document.documentElement.scrollTop ||
@ -260,12 +284,12 @@ function onScroll(e) {
multiTabsSetting.value.fixed &&
scrollTop >= 64
);
}
}
window.addEventListener('scroll', onScroll, true);
window.addEventListener('scroll', onScroll, true);
//
const delKeepAliveCompName = () => {
//
const delKeepAliveCompName = () => {
if (route.meta.keepAlive) {
const name = router.currentRoute.value.matched.find(
(item) => item.name == route.name
@ -275,17 +299,17 @@ const delKeepAliveCompName = () => {
asyncRouteStore.keepAliveComponents.filter((item) => item != name);
}
}
};
};
//
const tabsList: any = computed(() => tabsViewStore.tabsList);
const whiteList: string[] = [
//
const tabsList: any = computed(() => tabsViewStore.tabsList);
const whiteList: string[] = [
PageEnum.BASE_LOGIN_NAME,
PageEnum.REDIRECT_NAME,
PageEnum.ERROR_PAGE_NAME,
];
];
watch(
watch(
() => route.fullPath,
(to) => {
if (whiteList.includes(route.name as string)) return;
@ -294,73 +318,74 @@ watch(
updateNavScroll(true);
},
{ immediate: true }
);
);
//
window.addEventListener('beforeunload', () => {
//
window.addEventListener('beforeunload', () => {
storage.set(StorageEnum.ZS_TABS_ROUTES, JSON.stringify(tabsList.value));
});
});
//
const removeTab = (route) => {
//
const removeTab = (route) => {
if (tabsList.value.length === 1) {
return window['$message'].warning('这已经是最后一页,不能再关闭了!');
return message.warning('这已经是最后一页,不能再关闭了!');
}
delKeepAliveCompName();
tabsViewStore.closeCurrentTab(route);
//
if (state.activeKey === route.fullPath) {
const currentRoute = tabsList.value[Math.max(0, tabsList.value.length - 1)];
const currentRoute =
tabsList.value[Math.max(0, tabsList.value.length - 1)];
state.activeKey = currentRoute.fullPath;
router.push(currentRoute);
}
updateNavScroll();
};
};
//
const reloadPage = () => {
//
const reloadPage = () => {
delKeepAliveCompName();
router.push({
path: '/redirect' + route.fullPath,
});
};
};
//
provide('reloadPage', reloadPage);
//
provide('reloadPage', reloadPage);
//
const closeLeft = (route) => {
//
const closeLeft = (route) => {
tabsViewStore.closeLeftTabs(route);
state.activeKey = route.fullPath;
router.replace(route.fullPath);
updateNavScroll();
};
};
//
const closeRight = (route) => {
//
const closeRight = (route) => {
tabsViewStore.closeRightTabs(route);
state.activeKey = route.fullPath;
router.replace(route.fullPath);
updateNavScroll();
};
};
//
const closeOther = (route) => {
//
const closeOther = (route) => {
tabsViewStore.closeOtherTabs(route);
state.activeKey = route.fullPath;
router.replace(route.fullPath);
updateNavScroll();
};
};
//
const closeAll = () => {
//
const closeAll = () => {
tabsViewStore.closeAllTabs();
router.replace(PageEnum.BASE_HOME);
updateNavScroll();
};
};
//tab
const closeHandleSelect = (key) => {
//tab
const closeHandleSelect = (key) => {
switch (key) {
//
case '1':
@ -381,13 +406,13 @@ const closeHandleSelect = (key) => {
}
updateNavScroll();
state.showDropdown = false;
};
};
/**
/**
* @param value 要滚动到的位置
* @param amplitude 每次滚动的长度
*/
function scrollTo(value: number, amplitude: number) {
function scrollTo(value: number, amplitude: number) {
const currentScroll = navScroll.value.scrollLeft;
const scrollWidth =
(amplitude > 0 && currentScroll + amplitude >= value) ||
@ -397,9 +422,9 @@ function scrollTo(value: number, amplitude: number) {
navScroll.value && navScroll.value.scrollTo(scrollWidth, 0);
if (scrollWidth === value) return;
return window.requestAnimationFrame(() => scrollTo(value, amplitude));
}
}
function scrollPrev() {
function scrollPrev() {
const containerWidth = navScroll.value.offsetWidth;
const currentScroll = navScroll.value.scrollLeft;
@ -407,9 +432,9 @@ function scrollPrev() {
const scrollLeft =
currentScroll > containerWidth ? currentScroll - containerWidth : 0;
scrollTo(scrollLeft, (scrollLeft - currentScroll) / 20);
}
}
function scrollNext() {
function scrollNext() {
const containerWidth = navScroll.value.offsetWidth;
const navWidth = navScroll.value.scrollWidth;
const currentScroll = navScroll.value.scrollLeft;
@ -420,12 +445,12 @@ function scrollNext() {
? currentScroll + containerWidth
: navWidth - containerWidth;
scrollTo(scrollLeft, (scrollLeft - currentScroll) / 20);
}
}
/**
/**
* @param autoScroll 是否开启自动滚动功能
*/
async function updateNavScroll(autoScroll?: boolean) {
async function updateNavScroll(autoScroll?: boolean) {
await nextTick();
if (!navScroll.value) return;
const containerWidth = navScroll.value.offsetWidth;
@ -446,13 +471,13 @@ async function updateNavScroll(autoScroll?: boolean) {
} else {
state.scrollable = false;
}
}
}
function handleResize() {
function handleResize() {
updateNavScroll(true);
}
}
function handleContextMenu(e, item) {
function handleContextMenu(e, item) {
e.preventDefault();
isCurrent.value = PageEnum.BASE_HOME === item.path;
state.showDropdown = false;
@ -461,36 +486,66 @@ function handleContextMenu(e, item) {
state.dropdownX = e.clientX;
state.dropdownY = e.clientY;
});
}
}
function onClickOutside() {
function onClickOutside() {
state.showDropdown = false;
}
}
//tags
function goPage(e) {
//tags
function goPage(e) {
const { fullPath } = e;
if (fullPath === route.fullPath) return;
state.activeKey = fullPath;
go(e, true);
}
}
//tab
function closeTabItem(e) {
//tab
function closeTabItem(e) {
const { fullPath } = e;
const routeInfo = tabsList.value.find((item) => item.fullPath == fullPath);
const routeInfo = tabsList.value.find(
(item) => item.fullPath == fullPath
);
removeTab(routeInfo);
}
}
onMounted(() => {
onMounted(() => {
// onElementResize();
});
});
// function onElementResize() {
// let observer;
// observer = elementResizeDetectorMaker();
// observer.listenTo(navWrap.value, handleResize);
// }
// function onElementResize() {
// let observer;
// observer = elementResizeDetectorMaker();
// observer.listenTo(navWrap.value, handleResize);
// }
return {
...toRefs(state),
navWrap,
navScroll,
route,
tabsList,
goPage,
closeTabItem,
closeLeft,
closeRight,
closeOther,
closeAll,
reloadPage,
getChangeStyle,
TabsMenuOptions,
closeHandleSelect,
scrollNext,
scrollPrev,
handleContextMenu,
onClickOutside,
getDarkTheme,
getAppTheme,
getcardcolor,
getbasecolor,
};
},
});
</script>
<style lang="scss" scoped>