Merge branch 'dev' of github.com:youlaitech/vue3-element-admin
Former-commit-id: 852c9b4d01bdc17d5670f30348db3099899344b9
This commit is contained in:
66
src/layout/components/Sidebar/LeftMenu.vue
Normal file
66
src/layout/components/Sidebar/LeftMenu.vue
Normal file
@@ -0,0 +1,66 @@
|
||||
<script lang="ts" setup>
|
||||
import { useRoute } from "vue-router";
|
||||
import SidebarItem from "./SidebarItem.vue";
|
||||
import { useSettingsStore } from "@/store/modules/settings";
|
||||
import { useAppStore } from "@/store/modules/app";
|
||||
import variables from "@/styles/variables.module.scss";
|
||||
|
||||
import path from "path-browserify";
|
||||
import { isExternal } from "@/utils/index";
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
const appStore = useAppStore();
|
||||
const currRoute = useRoute();
|
||||
const layout = computed(() => settingsStore.layout);
|
||||
const props = defineProps({
|
||||
menuList: {
|
||||
required: true,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
type: Array<any>,
|
||||
},
|
||||
basePath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* 解析路径
|
||||
*
|
||||
* @param routePath 路由路径
|
||||
*/
|
||||
function resolvePath(routePath: string) {
|
||||
if (isExternal(routePath)) {
|
||||
return routePath;
|
||||
}
|
||||
if (isExternal(props.basePath)) {
|
||||
return props.basePath;
|
||||
}
|
||||
|
||||
// 完整路径 = 父级路径(/level/level_3) + 路由路径
|
||||
const fullPath = path.resolve(props.basePath, routePath); // 相对路径 → 绝对路径
|
||||
return fullPath;
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<el-menu
|
||||
:default-active="layout === 'top' ? '-' : currRoute.path"
|
||||
:collapse="!appStore.sidebar.opened"
|
||||
:background-color="variables.menuBg"
|
||||
:text-color="variables.menuText"
|
||||
:active-text-color="variables.menuActiveText"
|
||||
:unique-opened="false"
|
||||
:collapse-transition="false"
|
||||
:mode="layout === 'top' ? 'horizontal' : 'vertical'"
|
||||
>
|
||||
<sidebar-item
|
||||
v-for="route in menuList"
|
||||
:key="route.path"
|
||||
:item="route"
|
||||
:base-path="resolvePath(route.path)"
|
||||
:is-collapse="!appStore.sidebar.opened"
|
||||
/>
|
||||
</el-menu>
|
||||
</template>
|
||||
@@ -54,6 +54,7 @@ function hasOneShowingChild(children = [], parent: any) {
|
||||
// 2:如果无子路由, 复制当前路由信息作为其子路由,满足只拥有一个子路由的条件,所以返回 true
|
||||
if (showingChildren.length === 0) {
|
||||
onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -71,6 +72,7 @@ function resolvePath(routePath: string) {
|
||||
if (isExternal(props.basePath)) {
|
||||
return props.basePath;
|
||||
}
|
||||
|
||||
// 完整路径 = 父级路径(/level/level_3) + 路由路径
|
||||
const fullPath = path.resolve(props.basePath, routePath); // 相对路径 → 绝对路径
|
||||
return fullPath;
|
||||
|
||||
78
src/layout/components/Sidebar/TopMenu.vue
Normal file
78
src/layout/components/Sidebar/TopMenu.vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<script lang="ts" setup>
|
||||
import { usePermissionStore } from "@/store/modules/permission";
|
||||
import variables from "@/styles/variables.module.scss";
|
||||
import { useAppStore } from "@/store/modules/app";
|
||||
import { translateRouteTitleI18n } from "@/utils/i18n";
|
||||
import { useRouter } from "vue-router";
|
||||
const appStore = useAppStore();
|
||||
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) => {
|
||||
appStore.changeTopActive(index);
|
||||
permissionStore.getMixLeftMenu(index);
|
||||
const { mixLeftMenu } = permissionStore;
|
||||
goFirst(mixLeftMenu);
|
||||
};
|
||||
const permissionStore = usePermissionStore();
|
||||
const topMenu = ref<any[]>([]);
|
||||
onMounted(() => {
|
||||
topMenu.value = permissionStore.routes.filter(
|
||||
(item) => !item.meta || !item.meta.hidden
|
||||
);
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<el-scrollbar>
|
||||
<el-menu
|
||||
mode="horizontal"
|
||||
:default-active="activePath"
|
||||
:background-color="variables.menuBg"
|
||||
:text-color="variables.menuText"
|
||||
:active-text-color="variables.menuActiveText"
|
||||
@select="selectMenu"
|
||||
>
|
||||
<el-menu-item
|
||||
v-for="route in topMenu"
|
||||
:key="route.path"
|
||||
:index="route.path"
|
||||
>
|
||||
<template #title>
|
||||
<svg-icon
|
||||
v-if="route.meta && route.meta.icon"
|
||||
:icon-class="route.meta.icon"
|
||||
/>
|
||||
<span v-if="route.path === '/'"> 首页 </span>
|
||||
<template v-else>
|
||||
<span v-if="route.meta && route.meta.title">
|
||||
{{ translateRouteTitleI18n(route.meta.title) }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
<!-- <sidebar-item
|
||||
v-for="route in topMenu"
|
||||
:key="route.path"
|
||||
:item="route"
|
||||
:base-path="route.path"
|
||||
:is-collapse="false"
|
||||
/> -->
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.el-menu {
|
||||
height: 50px !important;
|
||||
}
|
||||
</style>
|
||||
@@ -1,18 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from "vue-router";
|
||||
import SidebarItem from "./SidebarItem.vue";
|
||||
import TopMenu from "./TopMenu.vue";
|
||||
import LeftMenu from "./LeftMenu.vue";
|
||||
import Logo from "./Logo.vue";
|
||||
|
||||
import { useSettingsStore } from "@/store/modules/settings";
|
||||
import { usePermissionStore } from "@/store/modules/permission";
|
||||
import { useAppStore } from "@/store/modules/app";
|
||||
import { storeToRefs } from "pinia";
|
||||
import variables from "@/styles/variables.module.scss";
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
const permissionStore = usePermissionStore();
|
||||
const appStore = useAppStore();
|
||||
const currRoute = useRoute();
|
||||
const { sidebarLogo } = storeToRefs(settingsStore);
|
||||
const layout = computed(() => settingsStore.layout);
|
||||
const showContent = ref(true);
|
||||
@@ -28,41 +25,86 @@ watch(
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="{ 'has-logo': sidebarLogo }" class="menu-wrap">
|
||||
<div
|
||||
:class="{ 'has-logo': sidebarLogo }"
|
||||
class="menu-wrap"
|
||||
v-if="layout !== 'mix'"
|
||||
>
|
||||
<logo v-if="sidebarLogo" :collapse="!appStore.sidebar.opened" />
|
||||
<el-scrollbar v-if="showContent">
|
||||
<el-menu
|
||||
:default-active="layout === 'top' ? '-' : currRoute.path"
|
||||
:collapse="!appStore.sidebar.opened"
|
||||
:background-color="variables.menuBg"
|
||||
:text-color="variables.menuText"
|
||||
:active-text-color="variables.menuActiveText"
|
||||
:unique-opened="false"
|
||||
:collapse-transition="false"
|
||||
:mode="layout === 'top' ? 'horizontal' : 'vertical'"
|
||||
>
|
||||
<sidebar-item
|
||||
v-for="route in permissionStore.routes"
|
||||
:key="route.path"
|
||||
:item="route"
|
||||
:base-path="route.path"
|
||||
:is-collapse="!appStore.sidebar.opened"
|
||||
/>
|
||||
</el-menu>
|
||||
<LeftMenu :menu-list="permissionStore.routes" base-path="" />
|
||||
</el-scrollbar>
|
||||
<NavRight v-if="layout === 'top'" />
|
||||
</div>
|
||||
<template v-else>
|
||||
<div :class="{ 'has-logo': sidebarLogo }" class="menu-wrap">
|
||||
<div class="header">
|
||||
<logo v-if="sidebarLogo" :collapse="!appStore.sidebar.opened" />
|
||||
<TopMenu />
|
||||
<NavRight />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
:deep(.setting-container) {
|
||||
.setting-item {
|
||||
color: #fff;
|
||||
|
||||
.svg-icon {
|
||||
margin-right: 0px;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.isMix {
|
||||
.menu-wrap {
|
||||
width: 100% !important;
|
||||
height: 50px;
|
||||
background-color: $menuBg;
|
||||
|
||||
:deep(.header) {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
// 顶部模式全局变量修改
|
||||
--el-menu-item-height: 50px;
|
||||
|
||||
.logo-wrap {
|
||||
width: $sideBarWidth;
|
||||
}
|
||||
|
||||
.el-menu {
|
||||
background-color: $menuBg;
|
||||
|
||||
.el-menu-item {
|
||||
color: $menuText;
|
||||
}
|
||||
}
|
||||
|
||||
.el-scrollbar {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.left-menu {
|
||||
display: inline-block;
|
||||
width: $sideBarWidth;
|
||||
background-color: $menuBg;
|
||||
|
||||
:deep(.el-menu) {
|
||||
background-color: $menuBg;
|
||||
|
||||
.el-menu-item {
|
||||
color: $menuText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,6 +10,9 @@ import { translateRouteTitleI18n } from "@/utils/i18n";
|
||||
|
||||
import { usePermissionStore } from "@/store/modules/permission";
|
||||
import { useTagsViewStore, TagView } from "@/store/modules/tagsView";
|
||||
import { useSettingsStore } from "@/store/modules/settings";
|
||||
import { useAppStore } from "@/store/modules/app";
|
||||
|
||||
import ScrollPane from "./ScrollPane.vue";
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@@ -18,8 +21,11 @@ const route = useRoute();
|
||||
|
||||
const permissionStore = usePermissionStore();
|
||||
const tagsViewStore = useTagsViewStore();
|
||||
const appStore = useAppStore();
|
||||
|
||||
const { visitedViews } = storeToRefs(tagsViewStore);
|
||||
const settingsStore = useSettingsStore();
|
||||
const layout = computed(() => settingsStore.layout);
|
||||
|
||||
const selectedTag = ref({});
|
||||
const scrollPaneRef = ref();
|
||||
@@ -226,7 +232,52 @@ function closeTagMenu() {
|
||||
function handleScroll() {
|
||||
closeTagMenu();
|
||||
}
|
||||
function findOutermostParent(tree: any[], findName: string) {
|
||||
let parentMap: any = {};
|
||||
|
||||
function buildParentMap(node: any, parent: any) {
|
||||
parentMap[node.name] = parent;
|
||||
|
||||
if (node.children) {
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
buildParentMap(node.children[i], node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < tree.length; i++) {
|
||||
buildParentMap(tree[i], null);
|
||||
}
|
||||
|
||||
let currentNode = parentMap[findName];
|
||||
while (currentNode) {
|
||||
if (!parentMap[currentNode.name]) {
|
||||
return currentNode;
|
||||
}
|
||||
currentNode = parentMap[currentNode.name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
const againActiveTop = (newVal: string) => {
|
||||
if (layout.value !== "mix") return;
|
||||
const parent = findOutermostParent(permissionStore.routes, newVal);
|
||||
if (appStore.activeTopMenu !== parent.path) {
|
||||
appStore.changeTopActive(parent.path);
|
||||
}
|
||||
};
|
||||
// 如果是混合模式,更改selectedTag,需要对应高亮的activeTop
|
||||
watch(
|
||||
() => route.name,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
againActiveTop(newVal as string);
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
onMounted(() => {
|
||||
initTags();
|
||||
});
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import Main from "./main.vue";
|
||||
import { computed, watchEffect } from "vue";
|
||||
import { useWindowSize } from "@vueuse/core";
|
||||
import { AppMain, Navbar, Settings, TagsView } from "./components/index";
|
||||
import Sidebar from "./components/Sidebar/index.vue";
|
||||
import RightPanel from "@/components/RightPanel/index.vue";
|
||||
import LeftMenu from "./components/Sidebar/LeftMenu.vue";
|
||||
|
||||
import { useAppStore } from "@/store/modules/app";
|
||||
import { useSettingsStore } from "@/store/modules/settings";
|
||||
|
||||
import { usePermissionStore } from "@/store/modules/permission";
|
||||
const permissionStore = usePermissionStore();
|
||||
const { width } = useWindowSize();
|
||||
|
||||
/**
|
||||
* 响应式布局容器固定宽度
|
||||
*
|
||||
@@ -22,10 +22,25 @@ const WIDTH = 992;
|
||||
const appStore = useAppStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
const fixedHeader = computed(() => settingsStore.fixedHeader);
|
||||
const showTagsView = computed(() => settingsStore.tagsView);
|
||||
const showSettings = computed(() => settingsStore.showSettings);
|
||||
const activeTopMenu = computed(() => {
|
||||
return appStore.activeTopMenu;
|
||||
});
|
||||
// 混合模式左侧菜单
|
||||
const mixLeftMenu = computed(() => {
|
||||
return permissionStore.mixLeftMenu;
|
||||
});
|
||||
const layout = computed(() => settingsStore.layout);
|
||||
watch(
|
||||
() => activeTopMenu.value,
|
||||
(newVal) => {
|
||||
if (layout.value !== "mix") return;
|
||||
permissionStore.getMixLeftMenu(newVal);
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
const classObj = computed(() => ({
|
||||
hideSidebar: !appStore.sidebar.opened,
|
||||
@@ -33,6 +48,7 @@ const classObj = computed(() => ({
|
||||
withoutAnimation: appStore.sidebar.withoutAnimation,
|
||||
mobile: appStore.device === "mobile",
|
||||
isTop: layout.value === "top",
|
||||
isMix: layout.value === "mix",
|
||||
}));
|
||||
|
||||
watchEffect(() => {
|
||||
@@ -66,21 +82,15 @@ function handleOutsideClick() {
|
||||
></div>
|
||||
|
||||
<Sidebar class="sidebar-container" />
|
||||
|
||||
<div :class="{ hasTagsView: showTagsView }" class="main-container">
|
||||
<div :class="{ 'fixed-header': fixedHeader }">
|
||||
<navbar v-if="layout !== 'top'" />
|
||||
<tags-view v-if="showTagsView" />
|
||||
<template v-if="layout === 'mix'">
|
||||
<div class="mix-wrap">
|
||||
<!-- :menu-list="mixLeftMenu -->
|
||||
<!-- :menu-list="permissionStore.routes -->
|
||||
<LeftMenu :menu-list="mixLeftMenu" :base-path="activeTopMenu" />
|
||||
<Main />
|
||||
</div>
|
||||
|
||||
<!--主页面-->
|
||||
<app-main />
|
||||
|
||||
<!-- 设置面板 -->
|
||||
<RightPanel v-if="showSettings">
|
||||
<settings />
|
||||
</RightPanel>
|
||||
</div>
|
||||
</template>
|
||||
<Main v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -137,7 +147,7 @@ function handleOutsideClick() {
|
||||
height: 50px;
|
||||
|
||||
:deep(.logo-wrap) {
|
||||
width: 210px;
|
||||
width: $sideBarWidth;
|
||||
}
|
||||
|
||||
:deep(.el-scrollbar) {
|
||||
@@ -155,4 +165,30 @@ function handleOutsideClick() {
|
||||
// 顶部模式全局变量修改
|
||||
--el-menu-item-height: 50px;
|
||||
}
|
||||
|
||||
.isMix {
|
||||
:deep(.main-container) {
|
||||
display: inline-block;
|
||||
width: calc(100% - #{$sideBarWidth});
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.mix-wrap {
|
||||
display: flex;
|
||||
padding-top: 50px;
|
||||
|
||||
.main-container {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.openSidebar {
|
||||
.mix-wrap {
|
||||
.el-menu {
|
||||
width: $sideBarWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
57
src/layout/main.vue
Normal file
57
src/layout/main.vue
Normal file
@@ -0,0 +1,57 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, watchEffect } from "vue";
|
||||
import { useWindowSize } from "@vueuse/core";
|
||||
import { AppMain, Navbar, Settings, TagsView } from "./components/index";
|
||||
import RightPanel from "@/components/RightPanel/index.vue";
|
||||
|
||||
import { useAppStore } from "@/store/modules/app";
|
||||
import { useSettingsStore } from "@/store/modules/settings";
|
||||
const { width } = useWindowSize();
|
||||
|
||||
/**
|
||||
* 响应式布局容器固定宽度
|
||||
*
|
||||
* 大屏(>=1200px)
|
||||
* 中屏(>=992px)
|
||||
* 小屏(>=768px)
|
||||
*/
|
||||
const WIDTH = 992;
|
||||
|
||||
const appStore = useAppStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
const fixedHeader = computed(() => settingsStore.fixedHeader);
|
||||
const showTagsView = computed(() => settingsStore.tagsView);
|
||||
const showSettings = computed(() => settingsStore.showSettings);
|
||||
const layout = computed(() => settingsStore.layout);
|
||||
|
||||
watchEffect(() => {
|
||||
if (width.value < WIDTH) {
|
||||
appStore.toggleDevice("mobile");
|
||||
appStore.closeSideBar(true);
|
||||
} else {
|
||||
appStore.toggleDevice("desktop");
|
||||
|
||||
if (width.value >= 1200) {
|
||||
//大屏
|
||||
appStore.openSideBar(true);
|
||||
} else {
|
||||
appStore.closeSideBar(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div :class="{ hasTagsView: showTagsView }" class="main-container">
|
||||
<div :class="{ 'fixed-header': fixedHeader }">
|
||||
<navbar v-if="layout === 'left'" />
|
||||
<tags-view v-if="showTagsView" />
|
||||
</div>
|
||||
<!--主页面-->
|
||||
<app-main />
|
||||
<!-- 设置面板 -->
|
||||
<RightPanel v-if="showSettings">
|
||||
<settings />
|
||||
</RightPanel>
|
||||
</div>
|
||||
</template>
|
||||
@@ -24,6 +24,7 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||
|
||||
{
|
||||
path: "/",
|
||||
name: "/",
|
||||
component: Layout,
|
||||
redirect: "/dashboard",
|
||||
children: [
|
||||
|
||||
@@ -14,11 +14,12 @@ export const useAppStore = defineStore("app", () => {
|
||||
const language = useStorage("language", defaultSettings.language);
|
||||
|
||||
const sidebarStatus = useStorage("sidebarStatus", "closed");
|
||||
|
||||
const sidebar = reactive({
|
||||
opened: sidebarStatus.value !== "closed",
|
||||
withoutAnimation: false,
|
||||
});
|
||||
|
||||
const activeTopMenu = useStorage("activeTop", "");
|
||||
/**
|
||||
* 根据语言标识读取对应的语言包
|
||||
*/
|
||||
@@ -68,18 +69,25 @@ export const useAppStore = defineStore("app", () => {
|
||||
function changeLanguage(val: string) {
|
||||
language.value = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* 混合模式顶部切换
|
||||
*/
|
||||
function changeTopActive(val: string) {
|
||||
activeTopMenu.value = val;
|
||||
}
|
||||
return {
|
||||
device,
|
||||
sidebar,
|
||||
language,
|
||||
locale,
|
||||
size,
|
||||
activeTopMenu,
|
||||
toggleDevice,
|
||||
changeSize,
|
||||
changeLanguage,
|
||||
toggleSidebar,
|
||||
closeSideBar,
|
||||
openSideBar,
|
||||
changeTopActive,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RouteRecordRaw } from "vue-router";
|
||||
import { RouteRecordRaw, useRouter } from "vue-router";
|
||||
import { defineStore } from "pinia";
|
||||
import { constantRoutes } from "@/router";
|
||||
import { store } from "@/store";
|
||||
@@ -41,12 +41,13 @@ const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
|
||||
|
||||
routes.forEach((route) => {
|
||||
const tmpRoute = { ...route }; // ES6扩展运算符复制新对象
|
||||
|
||||
if (!route.name) {
|
||||
tmpRoute.name = route.path;
|
||||
}
|
||||
// 判断用户(角色)是否有该路由的访问权限
|
||||
if (hasPermission(roles, tmpRoute)) {
|
||||
if (tmpRoute.component?.toString() == "Layout") {
|
||||
tmpRoute.component = Layout;
|
||||
console.log();
|
||||
} else {
|
||||
const component = modules[`../../views/${tmpRoute.component}.vue`];
|
||||
if (component) {
|
||||
@@ -97,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
|
||||
|
||||
@@ -144,15 +144,46 @@
|
||||
.sidebar-container {
|
||||
width: $sideBarWidth !important;
|
||||
transition: transform 0.28s;
|
||||
|
||||
.header {
|
||||
.logo-wrap {
|
||||
width: 63px !important;
|
||||
transition: transform 0.28s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.hideSidebar {
|
||||
&.hideSidebar:not(.isMix) {
|
||||
.sidebar-container {
|
||||
pointer-events: none;
|
||||
transition-duration: 0.3s;
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user