feat: 🎸 重构sider组件中
This commit is contained in:
parent
26d4c7c568
commit
51313d7116
|
@ -1,27 +1,23 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<menu-unfold-outlined
|
<svg
|
||||||
v-if="collapsed"
|
:class="{'is-active': !collapsed}"
|
||||||
class="trigger"
|
class="hamburger"
|
||||||
|
viewBox="0 0 1024 1024"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
@click="toggleCollapsed(!collapsed)"
|
@click="toggleCollapsed(!collapsed)"
|
||||||
/>
|
>
|
||||||
<menu-fold-outlined
|
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
|
||||||
v-else
|
</svg>
|
||||||
class="trigger"
|
|
||||||
@click="toggleCollapsed(!collapsed)"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType } from 'vue'
|
import { defineComponent, PropType } from 'vue'
|
||||||
// import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue'
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Hamburger',
|
name: 'Hamburger',
|
||||||
// components: {
|
|
||||||
// MenuUnfoldOutlined,
|
|
||||||
// MenuFoldOutlined
|
|
||||||
// },
|
|
||||||
props: {
|
props: {
|
||||||
collapsed: {
|
collapsed: {
|
||||||
type: Boolean as PropType<boolean>,
|
type: Boolean as PropType<boolean>,
|
||||||
|
@ -43,13 +39,13 @@ export default defineComponent({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.trigger {
|
.hamburger {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
transition: color 0.3s;
|
cursor: pointer;
|
||||||
height: @navbarHeight;
|
width: 20px;
|
||||||
line-height: @navbarHeight;
|
height: 20px;
|
||||||
}
|
}
|
||||||
.trigger:hover {
|
.hamburger.is-active {
|
||||||
color: #1890ff;
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -50,7 +50,7 @@ export default defineComponent({
|
||||||
padding-left: 18px;
|
padding-left: 18px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: @topSilderHeight;
|
height: @topSilderHeight;
|
||||||
max-width: 200px;
|
width: 100%;
|
||||||
img {
|
img {
|
||||||
width: 37px;
|
width: 37px;
|
||||||
height: 37px;
|
height: 37px;
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<i v-if="icon.includes('el-icon')" :class="[icon, 'sub-el-icon', 'anticon']" />
|
||||||
|
<svg-icon v-else :icon-class="icon" class="anticon" />
|
||||||
|
<slot name="title">
|
||||||
|
<span class="anticon-item">{{ title }}</span>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, PropType } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Item',
|
||||||
|
props: {
|
||||||
|
icon: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.anticon-item {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity .3s cubic-bezier(.645,.045,.355,1),width .3s cubic-bezier(.645,.045,.355,1);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<template>
|
||||||
|
<a v-if="isExternal(to)" :href="to" target="_blank" rel="noopener">
|
||||||
|
<slot />
|
||||||
|
</a>
|
||||||
|
<router-link v-else :to="to">
|
||||||
|
<slot />
|
||||||
|
</router-link>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, PropType } from 'vue'
|
||||||
|
import { isExternal } from '@/utils/validate'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
to: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
isExternal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -1,11 +1,94 @@
|
||||||
<template>
|
<template>
|
||||||
<div />
|
<template v-if="!item.meta?.hidden">
|
||||||
|
<template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.meta?.alwaysShow">
|
||||||
|
<el-menu-item :index="resolvePath(onlyOneChild.path)">
|
||||||
|
<item v-if="onlyOneChild.meta" :icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" :title="onlyOneChild.meta.title" />
|
||||||
|
<template #title>
|
||||||
|
{{ onlyOneChild.meta.title }}
|
||||||
|
</template>
|
||||||
|
</el-menu-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-submenu v-else :index="resolvePath(item.path)">
|
||||||
|
<template #title>
|
||||||
|
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
|
||||||
|
</template>
|
||||||
|
<sider-item
|
||||||
|
v-for="child in item.children"
|
||||||
|
:key="child.path"
|
||||||
|
:is-nest="true"
|
||||||
|
:item="child"
|
||||||
|
:base-path="resolvePath(child.path)"
|
||||||
|
/>
|
||||||
|
</el-submenu>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent, PropType, ref } from 'vue'
|
||||||
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
import path from 'path'
|
||||||
|
import { isExternal } from '@/utils/validate'
|
||||||
|
import Item from './Item.vue'
|
||||||
|
import AppLink from './Link.vue'
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SilderItem'
|
name: 'SiderItem',
|
||||||
|
components: { Item, AppLink },
|
||||||
|
props: {
|
||||||
|
// route object
|
||||||
|
item: {
|
||||||
|
type: Object as PropType<object>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isNest: {
|
||||||
|
type: Boolean as PropType<boolean>,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
basePath: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
const onlyOneChild = ref<any>(null)
|
||||||
|
|
||||||
|
function hasOneShowingChild(children: RouteRecordRaw[] = [], parent: RouteRecordRaw): boolean {
|
||||||
|
const showingChildren: RouteRecordRaw[] = children.filter((item: RouteRecordRaw) => {
|
||||||
|
if (item.meta && item.meta.hidden) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
// Temp set(will be used if only has one showing child)
|
||||||
|
onlyOneChild.value = item
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// When there is only one child router, the child router is displayed by default
|
||||||
|
if (showingChildren.length === 1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show parent if there are no child router to display
|
||||||
|
if (showingChildren.length === 0) {
|
||||||
|
onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolvePath(routePath: string): string {
|
||||||
|
if (isExternal(routePath)) {
|
||||||
|
return routePath
|
||||||
|
}
|
||||||
|
return path.resolve(props.basePath, routePath)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
onlyOneChild,
|
||||||
|
hasOneShowingChild,
|
||||||
|
resolvePath
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="{'has-logo':show_logo}">
|
<!-- <div :class="{'has-logo': showLogo}" class="sidebar-container"> -->
|
||||||
<el-scrollbar wrap-class="scrollbar-wrapper">
|
<!-- <el-scrollbar class="menu-wrap"> -->
|
||||||
<el-menu
|
<el-menu
|
||||||
:default-active="activeMenu"
|
:default-active="activeMenu"
|
||||||
:collapse="collapsed"
|
:collapse="collapsed"
|
||||||
:unique-opened="false"
|
:unique-opened="false"
|
||||||
|
:background-color="variables.menuBg"
|
||||||
|
:text-color="variables.menuText"
|
||||||
|
:active-text-color="variables.menuActiveText"
|
||||||
mode="vertical"
|
mode="vertical"
|
||||||
|
class="sidebar-container"
|
||||||
|
:class="{'sidebar__wrap--collapsed': collapsed}"
|
||||||
|
@select="selectMenu"
|
||||||
>
|
>
|
||||||
<sider-item
|
<sider-item
|
||||||
v-for="route in routers"
|
v-for="route in routers"
|
||||||
|
@ -14,8 +20,8 @@
|
||||||
:base-path="route.path"
|
:base-path="route.path"
|
||||||
/>
|
/>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-scrollbar>
|
<!-- </el-scrollbar> -->
|
||||||
</div>
|
<!-- </div> -->
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -25,9 +31,8 @@ import { permissionStore } from '_p/index/store/modules/permission'
|
||||||
import { appStore } from '_p/index/store/modules/app'
|
import { appStore } from '_p/index/store/modules/app'
|
||||||
import type { RouteRecordRaw, RouteLocationNormalizedLoaded } from 'vue-router'
|
import type { RouteRecordRaw, RouteLocationNormalizedLoaded } from 'vue-router'
|
||||||
import SiderItem from './SiderItem.vue'
|
import SiderItem from './SiderItem.vue'
|
||||||
// import variables from '@/styles/variables.less'
|
import variables from '@/styles/variables.less'
|
||||||
import config from '_p/index/config'
|
import { isExternal } from '@/utils/validate'
|
||||||
const { show_logo } = config
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { SiderItem },
|
components: { SiderItem },
|
||||||
|
@ -45,12 +50,23 @@ export default defineComponent({
|
||||||
return path
|
return path
|
||||||
})
|
})
|
||||||
const collapsed = computed(() => appStore.collapsed)
|
const collapsed = computed(() => appStore.collapsed)
|
||||||
|
const showLogo = computed(() => appStore.showLogo)
|
||||||
|
|
||||||
|
function selectMenu(path: string) {
|
||||||
|
if (isExternal(path)) {
|
||||||
|
window.open(path)
|
||||||
|
} else {
|
||||||
|
push(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
routers,
|
routers,
|
||||||
activeMenu,
|
activeMenu,
|
||||||
collapsed,
|
collapsed,
|
||||||
show_logo
|
showLogo,
|
||||||
|
variables,
|
||||||
|
selectMenu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -59,12 +75,24 @@ export default defineComponent({
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.sidebar-container {
|
.sidebar-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
background: @menuBg;
|
||||||
|
@{deep}(.svg-icon) {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.has-logo {
|
.has-logo {
|
||||||
height: calc(~"100% - @{topSilderHeight}");
|
height: calc(~"100% - @{topSilderHeight}");
|
||||||
}
|
}
|
||||||
.menu-wrap {
|
// .menu-wrap {
|
||||||
height: 100%;
|
// height: 100%;
|
||||||
overflow: hidden;
|
// overflow: hidden;
|
||||||
}
|
// @{deep}(.el-scrollbar__wrap) {
|
||||||
|
// overflow-x: hidden;
|
||||||
|
// overflow-y: auto;
|
||||||
|
// }
|
||||||
|
// @{deep}(.el-menu) {
|
||||||
|
// border-right: none;
|
||||||
|
// width: 100%;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- <i v-if="icon.includes('el-icon')" :class="[icon, 'sub-el-icon', 'anticon']" /> -->
|
<i v-if="icon.includes('el-icon')" :class="[icon, 'sub-el-icon', 'anticon']" />
|
||||||
<svg-icon :icon-class="icon" class="anticon" />
|
<svg-icon v-else :icon-class="icon" class="anticon" />
|
||||||
<slot name="title">
|
<slot name="title">
|
||||||
<span class="anticon-item">{{ title }}</span>
|
<span class="anticon-item">{{ title }}</span>
|
||||||
</slot>
|
</slot>
|
||||||
|
|
|
@ -1,25 +1,29 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app__wrap">
|
<el-container class="app__wrap">
|
||||||
<div class="sidebar__wrap">
|
<div class="sidebar__wrap" :class="{'sidebar__wrap--collapsed': collapsed}">
|
||||||
<logo
|
<logo
|
||||||
v-if="show_logo"
|
v-if="showLogo"
|
||||||
:collapsed="collapsed"
|
:collapsed="collapsed"
|
||||||
/>
|
/>
|
||||||
<sider /></div>
|
<sider />
|
||||||
|
</div>
|
||||||
|
<el-main><hamburger :collapsed="collapsed" class="hamburger-container" @toggleClick="setCollapsed" /></el-main>
|
||||||
|
</el-container>
|
||||||
|
<!-- <div class="app__wrap">
|
||||||
|
<div class="sidebar__wrap" :class="{'sidebar__wrap--collapsed': collapsed}">
|
||||||
|
<logo
|
||||||
|
v-if="showLogo"
|
||||||
|
:collapsed="collapsed"
|
||||||
|
/>
|
||||||
|
<sider />
|
||||||
|
</div>
|
||||||
<div class="main__wrap">
|
<div class="main__wrap">
|
||||||
<div class="navbar__wrap" />
|
<div class="navbar__wrap">
|
||||||
|
</div>
|
||||||
<div class="tags__wrap" />
|
<div class="tags__wrap" />
|
||||||
<div class="main__wrap" />
|
<div class="main__wrap" />
|
||||||
</div>
|
</div>
|
||||||
<!-- <sidebar class="sidebar-wrap" />
|
|
||||||
<div :class="{hasTagsView: has_tags}" class="main-wrap">
|
|
||||||
<div>
|
|
||||||
<navbar />
|
|
||||||
<tags-view v-if="has_tags" />
|
|
||||||
</div>
|
|
||||||
<app-main />
|
|
||||||
</div> -->
|
</div> -->
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -31,32 +35,63 @@ import TagsView from '../components/TagsView.vue'
|
||||||
import Logo from '_c/Logo/index.vue'
|
import Logo from '_c/Logo/index.vue'
|
||||||
import Scrollbar from '_c/Scrollbar/index.vue'
|
import Scrollbar from '_c/Scrollbar/index.vue'
|
||||||
import Sider from '_c/Sider/index.vue'
|
import Sider from '_c/Sider/index.vue'
|
||||||
import Navbar from '../components/Navbar.vue'
|
import Hamburger from '_c/Hamburger/index.vue'
|
||||||
|
|
||||||
import config from '_p/index/config'
|
|
||||||
const { show_logo, has_tags } = config
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Layout',
|
name: 'Layout',
|
||||||
components: {
|
components: {
|
||||||
Sider,
|
Sider,
|
||||||
Navbar,
|
Hamburger,
|
||||||
|
// Navbar,
|
||||||
AppMain,
|
AppMain,
|
||||||
TagsView,
|
TagsView,
|
||||||
Logo,
|
Logo,
|
||||||
Scrollbar
|
Scrollbar
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
const collapsed = computed(() => appStore.collapsed)
|
||||||
|
const showLogo = computed(() => appStore.showLogo)
|
||||||
|
const showTags = computed(() => appStore.showTags)
|
||||||
|
|
||||||
|
function setCollapsed(collapsed: boolean): void {
|
||||||
|
appStore.SetCollapsed(collapsed)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
show_logo, has_tags
|
collapsed,
|
||||||
|
showLogo,
|
||||||
|
showTags,
|
||||||
|
setCollapsed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.app-wrap {
|
.app__wrap {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
// .sidebar__wrap {
|
||||||
|
// position: absolute;
|
||||||
|
// width: @menuWidth;
|
||||||
|
// top: 0;
|
||||||
|
// left: 0;
|
||||||
|
// height: 100%;
|
||||||
|
// transition: all 0.2s;
|
||||||
|
// }
|
||||||
|
// .sidebar__wrap--collapsed {
|
||||||
|
// width: @menuMinWidth;
|
||||||
|
|
||||||
|
// }
|
||||||
|
// .main__wrap {
|
||||||
|
// position: absolute;
|
||||||
|
// width: calc(~"100% - @{menuWidth}");
|
||||||
|
// height: 100%;
|
||||||
|
// top: 0;
|
||||||
|
// left: @menuWidth;
|
||||||
|
// .navbar__wrap {
|
||||||
|
// height: @navbarHeight;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -357,65 +357,65 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
|
||||||
// }
|
// }
|
||||||
// ]
|
// ]
|
||||||
// },
|
// },
|
||||||
// {
|
{
|
||||||
// path: '/level',
|
path: '/level',
|
||||||
// component: Layout,
|
component: Layout,
|
||||||
// redirect: '/level/menu1/menu1-1/menu1-1-1',
|
redirect: '/level/menu1/menu1-1/menu1-1-1',
|
||||||
// name: 'Level',
|
name: 'Level',
|
||||||
// meta: {
|
meta: {
|
||||||
// title: '多级菜单缓存',
|
title: '多级菜单缓存',
|
||||||
// icon: 'nested'
|
icon: 'nested'
|
||||||
// },
|
},
|
||||||
// children: [
|
children: [
|
||||||
// {
|
{
|
||||||
// path: 'menu1',
|
path: 'menu1',
|
||||||
// name: 'Menu1Demo',
|
name: 'Menu1Demo',
|
||||||
// component: getParentLayout('Menu1Demo'),
|
component: getParentLayout('Menu1Demo'),
|
||||||
// redirect: '/level/menu1/menu1-1/menu1-1-1',
|
redirect: '/level/menu1/menu1-1/menu1-1-1',
|
||||||
// meta: {
|
meta: {
|
||||||
// title: 'Menu1'
|
title: 'Menu1'
|
||||||
// },
|
},
|
||||||
// children: [
|
children: [
|
||||||
// {
|
{
|
||||||
// path: 'menu1-1',
|
path: 'menu1-1',
|
||||||
// name: 'Menu11Demo',
|
name: 'Menu11Demo',
|
||||||
// component: getParentLayout('Menu11Demo'),
|
component: getParentLayout('Menu11Demo'),
|
||||||
// redirect: '/level/menu1/menu1-1/menu1-1-1',
|
redirect: '/level/menu1/menu1-1/menu1-1-1',
|
||||||
// meta: {
|
meta: {
|
||||||
// title: 'Menu1-1',
|
title: 'Menu1-1',
|
||||||
// alwaysShow: true
|
alwaysShow: true
|
||||||
// },
|
},
|
||||||
// children: [
|
children: [
|
||||||
// {
|
{
|
||||||
// path: 'menu1-1-1',
|
path: 'menu1-1-1',
|
||||||
// name: 'Menu111Demo',
|
name: 'Menu111Demo',
|
||||||
// component: () => import('_p/index/views/level/Menu111.vue'),
|
component: () => import('_p/index/views/level/Menu111.vue'),
|
||||||
// meta: {
|
meta: {
|
||||||
// title: 'Menu1-1-1'
|
title: 'Menu1-1-1'
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// ]
|
]
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// path: 'menu1-2',
|
path: 'menu1-2',
|
||||||
// name: 'Menu12Demo',
|
name: 'Menu12Demo',
|
||||||
// component: () => import('_p/index/views/level/Menu12.vue'),
|
component: () => import('_p/index/views/level/Menu12.vue'),
|
||||||
// meta: {
|
meta: {
|
||||||
// title: 'Menu1-2'
|
title: 'Menu1-2'
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// ]
|
]
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// path: 'menu2',
|
path: 'menu2',
|
||||||
// name: 'Menu2Demo',
|
name: 'Menu2Demo',
|
||||||
// component: () => import('_p/index/views/level/Menu2.vue'),
|
component: () => import('_p/index/views/level/Menu2.vue'),
|
||||||
// meta: {
|
meta: {
|
||||||
// title: 'Menu2'
|
title: 'Menu2'
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// ]
|
]
|
||||||
// },
|
},
|
||||||
// {
|
// {
|
||||||
// path: '/example-demo',
|
// path: '/example-demo',
|
||||||
// component: Layout,
|
// component: Layout,
|
||||||
|
|
|
@ -14,7 +14,7 @@ export interface AppState {
|
||||||
@Module({ dynamic: true, namespaced: true, store, name: 'app' })
|
@Module({ dynamic: true, namespaced: true, store, name: 'app' })
|
||||||
class App extends VuexModule implements AppState {
|
class App extends VuexModule implements AppState {
|
||||||
public collapsed = false // 菜单栏是否栏缩收
|
public collapsed = false // 菜单栏是否栏缩收
|
||||||
public showLogo = true // 是否显示logo
|
public showLogo = false // 是否显示logo
|
||||||
public showTags = true // 是否显示标签栏
|
public showTags = true // 是否显示标签栏
|
||||||
public showNavbar = true // 是否显示navbar
|
public showNavbar = true // 是否显示navbar
|
||||||
public fixedTags = true // 是否固定标签栏
|
public fixedTags = true // 是否固定标签栏
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div style="padding: 20px; background: #fff;display: flex;align-items: center;">
|
<div style="padding: 20px; background: #fff;display: flex;align-items: center;">
|
||||||
<div style="min-width: 200px;">多层级缓存-页面1-1-1:</div>
|
<div style="min-width: 200px;">多层级缓存-页面1-1-1:</div>
|
||||||
<a-input />
|
<el-input />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div style="padding: 20px; background: #fff;display: flex;align-items: center;">
|
<div style="padding: 20px; background: #fff;display: flex;align-items: center;">
|
||||||
<div style="min-width: 200px;">多层级缓存-页面1-2:</div>
|
<div style="min-width: 200px;">多层级缓存-页面1-2:</div>
|
||||||
<a-input />
|
<el-input />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div style="padding: 20px; background: #fff;display: flex;align-items: center;">
|
<div style="padding: 20px; background: #fff;display: flex;align-items: center;">
|
||||||
<div style="min-width: 200px;">多层级缓存-页面2:</div>
|
<div style="min-width: 200px;">多层级缓存-页面2:</div>
|
||||||
<a-input />
|
<el-input />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@import '~element-plus/lib/theme-chalk/index.css';
|
@import '~element-plus/lib/theme-chalk/index.css';
|
||||||
|
// @import './sidebar.less';
|
||||||
@import './transition.less';
|
@import './transition.less';
|
||||||
@import './silder.less';
|
@import './silder.less';
|
||||||
@import './glob.less';
|
@import './glob.less';
|
||||||
|
|
|
@ -0,0 +1,234 @@
|
||||||
|
#app {
|
||||||
|
|
||||||
|
// 主体区域 Main container
|
||||||
|
.main-container {
|
||||||
|
min-height: 100%;
|
||||||
|
transition: margin-left .28s;
|
||||||
|
margin-left: @menuWidth;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 侧边栏 Sidebar container
|
||||||
|
.sidebar-container {
|
||||||
|
transition: width 0.28s;
|
||||||
|
width: @menuWidth !important;
|
||||||
|
height: 100%;
|
||||||
|
position: fixed;
|
||||||
|
font-size: 0px;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1001;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
//reset element-ui css
|
||||||
|
.horizontal-collapse-transition {
|
||||||
|
transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-wrapper {
|
||||||
|
overflow-x: hidden !important;
|
||||||
|
|
||||||
|
.el-scrollbar__view {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-scrollbar__bar.is-vertical {
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-scrollbar {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.has-logo {
|
||||||
|
.el-scrollbar {
|
||||||
|
height: calc(100% - 70px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-horizontal {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-icon {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-menu {
|
||||||
|
border: none;
|
||||||
|
height: 100%;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// menu hover
|
||||||
|
.submenu-title-noDropdown,
|
||||||
|
.el-submenu__title {
|
||||||
|
color: hsla(0,0%,100%,.7) !important;
|
||||||
|
&:hover {
|
||||||
|
// background-color: @menuHover !important;
|
||||||
|
color: @subMenuActiveText !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-active>.el-submenu__title {
|
||||||
|
color: @subMenuActiveText !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-active {
|
||||||
|
color: @subMenuActiveText !important;
|
||||||
|
background-color: @menuActiveBg !important;
|
||||||
|
&:hover {
|
||||||
|
color: @subMenuActiveText !important;
|
||||||
|
background-color: @menuActiveBg !important;
|
||||||
|
}
|
||||||
|
& .el-menu-item {
|
||||||
|
background-color: @menuActiveBg !important;
|
||||||
|
&:hover {
|
||||||
|
color: @subMenuActiveText !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .nest-menu .el-submenu>.el-submenu__title,
|
||||||
|
& .el-submenu .el-menu-item {
|
||||||
|
min-width: @menuWidth !important;
|
||||||
|
background-color: @subMenuBg !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: @subMenuActiveText !important;
|
||||||
|
background-color: @subMenuHover !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .nest-menu {
|
||||||
|
& .is-active {
|
||||||
|
background-color: @menuActiveBg !important;
|
||||||
|
&:hover {
|
||||||
|
color: @subMenuActiveText !important;
|
||||||
|
background-color: @menuActiveBg !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hideSidebar {
|
||||||
|
.sidebar-container {
|
||||||
|
width: 36px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-container {
|
||||||
|
margin-left: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenu-title-noDropdown {
|
||||||
|
padding-left: 10px !important;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.el-tooltip {
|
||||||
|
padding: 0 10px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-submenu {
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&>.el-submenu__title {
|
||||||
|
padding-left: 10px !important;
|
||||||
|
|
||||||
|
.el-submenu__icon-arrow {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-menu--collapse {
|
||||||
|
.el-submenu {
|
||||||
|
&>.el-submenu__title {
|
||||||
|
&>span {
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-menu--collapse .el-menu .el-submenu {
|
||||||
|
min-width: @menuWidth !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 适配移动端, Mobile responsive
|
||||||
|
.mobile {
|
||||||
|
.main-container {
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-container {
|
||||||
|
transition: transform .28s;
|
||||||
|
width: @menuWidth !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.hideSidebar {
|
||||||
|
.sidebar-container {
|
||||||
|
pointer-events: none;
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
transform: translate3d(-@menuWidth, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.withoutAnimation {
|
||||||
|
|
||||||
|
.main-container,
|
||||||
|
.sidebar-container {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// when menu collapsed
|
||||||
|
.el-menu--vertical {
|
||||||
|
&>.el-menu {
|
||||||
|
.svg-icon {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nest-menu .el-submenu>.el-submenu__title,
|
||||||
|
.el-menu-item {
|
||||||
|
&:hover {
|
||||||
|
// you can use @subMenuHover
|
||||||
|
// background-color: @menuHover !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the scroll bar appears when the subMenu is too long
|
||||||
|
>.el-menu--popup {
|
||||||
|
max-height: 100vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track-piece {
|
||||||
|
background: #d3dce6;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: #99a9bf;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,25 @@
|
||||||
// Silder
|
// Silder
|
||||||
|
@menuText: #bfcbd9;
|
||||||
|
@menuActiveText: #409EFF;
|
||||||
|
@menuActiveBg: #2d8cf0;
|
||||||
|
|
||||||
|
@menuBg: #001529;
|
||||||
|
|
||||||
|
@subMenuBg: #1f2d3d;
|
||||||
|
@subMenuHover: #1f2d3d;
|
||||||
|
@subMenuActiveText: #fff;
|
||||||
|
|
||||||
|
@menuWidth: 200px;
|
||||||
|
@menuMinWidth: 64px;
|
||||||
|
|
||||||
@menuLightActiveText: #1890ff;
|
@menuLightActiveText: #1890ff;
|
||||||
@menuLightActiveBg: #e6f7ff;
|
@menuLightActiveBg: #e6f7ff;
|
||||||
|
|
||||||
@menuDarkActiveText: #fff;
|
@menuDarkActiveText: #fff;
|
||||||
@menuDarkActiveBg: #1890ff;
|
@menuDarkActiveBg: #1890ff;
|
||||||
|
|
||||||
@menuBg: #001529;
|
|
||||||
@menuLightBg: #fff;
|
@menuLightBg: #fff;
|
||||||
|
|
||||||
@menuWidth: 200px;
|
|
||||||
|
|
||||||
// topSilder
|
// topSilder
|
||||||
@topSilderHeight: 50px;
|
@topSilderHeight: 50px;
|
||||||
|
|
||||||
|
@ -27,3 +37,15 @@
|
||||||
|
|
||||||
// deep
|
// deep
|
||||||
@deep: ~'::v-deep';
|
@deep: ~'::v-deep';
|
||||||
|
|
||||||
|
// the :export directive is the magic sauce for webpack
|
||||||
|
:export {
|
||||||
|
menuText: @menuText;
|
||||||
|
menuActiveText: @menuActiveText;
|
||||||
|
menuActiveBg: @menuActiveBg;
|
||||||
|
menuBg: @menuBg;
|
||||||
|
subMenuBg: @subMenuBg;
|
||||||
|
subMenuHover: @subMenuHover;
|
||||||
|
menuWidth: @menuWidth;
|
||||||
|
menuMinWidth: @menuMinWidth;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
export interface IScssVariables {
|
||||||
|
menuText: string
|
||||||
|
menuActiveText: string
|
||||||
|
menuActiveBg: string
|
||||||
|
menuBg: string
|
||||||
|
subMenuBg: string
|
||||||
|
subMenuHover: string
|
||||||
|
menuWidth: string
|
||||||
|
menuMinWidth: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const variables: IScssVariables
|
||||||
|
|
||||||
|
export default variables
|
Loading…
Reference in New Issue