feat: 导航混合模式细节完善
This commit is contained in:
parent
d2991ed15f
commit
aa7373f063
|
|
@ -5,7 +5,8 @@ root = true
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8 # 设置文件字符集为 utf-8
|
charset = utf-8 # 设置文件字符集为 utf-8
|
||||||
end_of_line = lf # 控制换行类型(lf | cr | crlf)
|
end_of_line = lf # 控制换行类型(lf | cr | crlf)
|
||||||
indent_style = tab # 缩进风格(tab | space)
|
indent_style = space # 缩进风格(tab | space)
|
||||||
|
indent_size = 2 # 缩进大小
|
||||||
insert_final_newline = true # 始终在文件末尾插入一个新行
|
insert_final_newline = true # 始终在文件末尾插入一个新行
|
||||||
|
|
||||||
# 表示仅 md 文件适用以下规则
|
# 表示仅 md 文件适用以下规则
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,12 @@ module.exports = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"vue/multi-word-component-names": "off",
|
"vue/multi-word-component-names": "off",
|
||||||
|
"prettier/prettier": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
useTabs: false, // 不使用制表符
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
// eslint不能对html文件生效
|
// eslint不能对html文件生效
|
||||||
overrides: [
|
overrides: [
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,34 @@ import { usePermissionStore } from "@/store/modules/permission";
|
||||||
import variables from "@/styles/variables.module.scss";
|
import variables from "@/styles/variables.module.scss";
|
||||||
import { useAppStore } from "@/store/modules/app";
|
import { useAppStore } from "@/store/modules/app";
|
||||||
import { translateRouteTitleI18n } from "@/utils/i18n";
|
import { translateRouteTitleI18n } from "@/utils/i18n";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const activePath = computed(() => appStore.activeTopMenu);
|
const activePath = computed(() => appStore.activeTopMenu);
|
||||||
|
const router = useRouter();
|
||||||
|
// 递归跳转
|
||||||
|
const goFirst = (menu: any[]) => {
|
||||||
|
if (!menu.length) return;
|
||||||
|
const [first] = menu;
|
||||||
|
if (first.children) {
|
||||||
|
goFirst(first.children);
|
||||||
|
} else {
|
||||||
|
router.push({
|
||||||
|
name: first.name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
const selectMenu = (index: string) => {
|
const selectMenu = (index: string) => {
|
||||||
appStore.changeTopActive(index);
|
appStore.changeTopActive(index);
|
||||||
|
permissionStore.getMixLeftMenu(index);
|
||||||
|
const { mixLeftMenu } = permissionStore;
|
||||||
|
goFirst(mixLeftMenu);
|
||||||
};
|
};
|
||||||
const permissionStore = usePermissionStore();
|
const permissionStore = usePermissionStore();
|
||||||
const topMenu = ref<any[]>([]);
|
const topMenu = ref<any[]>([]);
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
topMenu.value = permissionStore.routes.filter((el) => !el.meta?.hidden);
|
topMenu.value = permissionStore.routes.filter(
|
||||||
|
(item) => !item.meta || !item.meta.hidden
|
||||||
|
);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -34,9 +53,12 @@ onMounted(() => {
|
||||||
v-if="route.meta && route.meta.icon"
|
v-if="route.meta && route.meta.icon"
|
||||||
:icon-class="route.meta.icon"
|
:icon-class="route.meta.icon"
|
||||||
/>
|
/>
|
||||||
<span v-if="route.meta && route.meta.title">{{
|
<span v-if="route.path === '/'"> 首页 </span>
|
||||||
translateRouteTitleI18n(route.meta.title)
|
<template v-else>
|
||||||
}}</span>
|
<span v-if="route.meta && route.meta.title">
|
||||||
|
{{ translateRouteTitleI18n(route.meta.title) }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<!-- <sidebar-item
|
<!-- <sidebar-item
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ watch(
|
||||||
--el-menu-item-height: 50px;
|
--el-menu-item-height: 50px;
|
||||||
|
|
||||||
.logo-wrap {
|
.logo-wrap {
|
||||||
width: 210px;
|
width: $sideBarWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-menu {
|
.el-menu {
|
||||||
|
|
@ -95,7 +95,7 @@ watch(
|
||||||
|
|
||||||
.left-menu {
|
.left-menu {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 210px;
|
width: $sideBarWidth;
|
||||||
background-color: $menuBg;
|
background-color: $menuBg;
|
||||||
|
|
||||||
:deep(.el-menu) {
|
:deep(.el-menu) {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import LeftMenu from "./components/Sidebar/LeftMenu.vue";
|
||||||
import { useAppStore } from "@/store/modules/app";
|
import { useAppStore } from "@/store/modules/app";
|
||||||
import { useSettingsStore } from "@/store/modules/settings";
|
import { useSettingsStore } from "@/store/modules/settings";
|
||||||
import { usePermissionStore } from "@/store/modules/permission";
|
import { usePermissionStore } from "@/store/modules/permission";
|
||||||
import { useRouter } from "vue-router";
|
|
||||||
const permissionStore = usePermissionStore();
|
const permissionStore = usePermissionStore();
|
||||||
const { width } = useWindowSize();
|
const { width } = useWindowSize();
|
||||||
/**
|
/**
|
||||||
|
|
@ -27,23 +26,15 @@ const activeTopMenu = computed(() => {
|
||||||
return appStore.activeTopMenu;
|
return appStore.activeTopMenu;
|
||||||
});
|
});
|
||||||
// 混合模式左侧菜单
|
// 混合模式左侧菜单
|
||||||
const mixLeftMenu = ref<any[]>([]);
|
const mixLeftMenu = computed(() => {
|
||||||
const router = useRouter();
|
return permissionStore.mixLeftMenu;
|
||||||
|
});
|
||||||
const layout = computed(() => settingsStore.layout);
|
const layout = computed(() => settingsStore.layout);
|
||||||
watch(
|
watch(
|
||||||
() => activeTopMenu.value,
|
() => activeTopMenu.value,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
if (layout.value !== "mix") return;
|
if (layout.value !== "mix") return;
|
||||||
permissionStore.routes.forEach((item) => {
|
permissionStore.getMixLeftMenu(newVal);
|
||||||
if (item.path === newVal) {
|
|
||||||
mixLeftMenu.value = item.children || [];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (mixLeftMenu.value) {
|
|
||||||
router.push({
|
|
||||||
name: mixLeftMenu.value[0].name,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true,
|
deep: true,
|
||||||
|
|
@ -156,7 +147,7 @@ function handleOutsideClick() {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
|
|
||||||
:deep(.logo-wrap) {
|
:deep(.logo-wrap) {
|
||||||
width: 210px;
|
width: $sideBarWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-scrollbar) {
|
:deep(.el-scrollbar) {
|
||||||
|
|
@ -178,7 +169,7 @@ function handleOutsideClick() {
|
||||||
.isMix {
|
.isMix {
|
||||||
:deep(.main-container) {
|
:deep(.main-container) {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: calc(100% - 210px);
|
width: calc(100% - #{$sideBarWidth});
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,14 +177,18 @@ function handleOutsideClick() {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-top: 50px;
|
padding-top: 50px;
|
||||||
|
|
||||||
.el-menu {
|
|
||||||
width: 210px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-container {
|
.main-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.openSidebar {
|
||||||
|
.mix-wrap {
|
||||||
|
.el-menu {
|
||||||
|
width: $sideBarWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
|
name: "/",
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: "/dashboard",
|
redirect: "/dashboard",
|
||||||
children: [
|
children: [
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { RouteRecordRaw } from "vue-router";
|
import { RouteRecordRaw, useRouter } from "vue-router";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { constantRoutes } from "@/router";
|
import { constantRoutes } from "@/router";
|
||||||
import { store } from "@/store";
|
import { store } from "@/store";
|
||||||
|
|
@ -48,7 +48,6 @@ const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
|
||||||
if (hasPermission(roles, tmpRoute)) {
|
if (hasPermission(roles, tmpRoute)) {
|
||||||
if (tmpRoute.component?.toString() == "Layout") {
|
if (tmpRoute.component?.toString() == "Layout") {
|
||||||
tmpRoute.component = Layout;
|
tmpRoute.component = Layout;
|
||||||
console.log();
|
|
||||||
} else {
|
} else {
|
||||||
const component = modules[`../../views/${tmpRoute.component}.vue`];
|
const component = modules[`../../views/${tmpRoute.component}.vue`];
|
||||||
if (component) {
|
if (component) {
|
||||||
|
|
@ -99,7 +98,19 @@ export const usePermissionStore = defineStore("permission", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return { routes, setRoutes, generateRoutes };
|
|
||||||
|
/**
|
||||||
|
* 混合模式左侧菜单
|
||||||
|
*/
|
||||||
|
const mixLeftMenu = ref<RouteRecordRaw[]>([]);
|
||||||
|
function getMixLeftMenu(activeTop: string) {
|
||||||
|
routes.value.forEach((item) => {
|
||||||
|
if (item.path === activeTop) {
|
||||||
|
mixLeftMenu.value = item.children || [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { routes, setRoutes, generateRoutes, getMixLeftMenu, mixLeftMenu };
|
||||||
});
|
});
|
||||||
|
|
||||||
// 非setup
|
// 非setup
|
||||||
|
|
|
||||||
|
|
@ -144,15 +144,46 @@
|
||||||
.sidebar-container {
|
.sidebar-container {
|
||||||
width: $sideBarWidth !important;
|
width: $sideBarWidth !important;
|
||||||
transition: transform 0.28s;
|
transition: transform 0.28s;
|
||||||
|
|
||||||
|
.header {
|
||||||
|
.logo-wrap {
|
||||||
|
width: 63px !important;
|
||||||
|
transition: transform 0.28s;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.hideSidebar {
|
&.hideSidebar:not(.isMix) {
|
||||||
.sidebar-container {
|
.sidebar-container {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
transition-duration: 0.3s;
|
transition-duration: 0.3s;
|
||||||
transform: translate3d(-$sideBarWidth, 0, 0);
|
transform: translate3d(-$sideBarWidth, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.hideSidebar {
|
||||||
|
.isMix {
|
||||||
|
:deep(.sidebar-container) {
|
||||||
|
.header {
|
||||||
|
.logo-wrap {
|
||||||
|
width: 64px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.openSidebar {
|
||||||
|
.isMix {
|
||||||
|
:deep(.sidebar-container) {
|
||||||
|
.header {
|
||||||
|
.logo-wrap {
|
||||||
|
width: 210px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.withoutAnimation {
|
.withoutAnimation {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue