'admin-21.01.11:新增布局配置布局切换'

This commit is contained in:
lyt-Top 2021-01-10 23:59:43 +08:00
parent f54128568d
commit de03cda45e
22 changed files with 621 additions and 62 deletions

View File

@ -11,8 +11,10 @@ export interface RootStateTypes {
danger: string, danger: string,
topBar: string, topBar: string,
menuBar: string, menuBar: string,
columnsMenuBar: string,
topBarColor: string, topBarColor: string,
menuBarColor: string, menuBarColor: string,
columnsMenuBarColor: string,
isTopBarColorGradual: boolean, isTopBarColorGradual: boolean,
isMenuBarColorGradual: boolean, isMenuBarColorGradual: boolean,
isMenuBarColorHighlight: boolean, isMenuBarColorHighlight: boolean,
@ -32,7 +34,8 @@ export interface RootStateTypes {
isWartermark: boolean, isWartermark: boolean,
wartermarkText: string, wartermarkText: string,
tagsStyle: string, tagsStyle: string,
animation: string animation: string,
layout: string
} }
} }

View File

@ -45,22 +45,34 @@ body,
} }
.el-main { .el-main {
padding: 0 !important; padding: 0 !important;
overflow: hidden;
} }
.el-scrollbar { .el-scrollbar {
width: 100%; width: 100%;
} }
.layout-el-aside-br-color {
border-top: 1px solid rgb(238, 238, 238);
border-right: 1px solid rgb(238, 238, 238);
}
.layout-aside-width-default { .layout-aside-width-default {
width: 240px !important; width: 220px !important;
transition: width 0.3s ease; transition: width 0.3s ease;
} }
.layout-aside-width64 { .layout-aside-width64 {
width: 64px !important; width: 64px !important;
transition: width 0.3s ease; transition: width 0.3s ease;
} }
.layout-aside-width1 {
width: 1px !important;
transition: width 0.3s ease;
}
.layout-scrollbar { .layout-scrollbar {
@extend .el-scrollbar; @extend .el-scrollbar;
padding: 15px; padding: 15px;
} }
.layout-mian-height-50 {
height: calc(100vh - 50px);
}
} }
/* element plus 全局样式 /* element plus 全局样式

View File

@ -60,8 +60,10 @@ $--color-danger-light-8: mix($--color-whites, $--color-danger, 80%) !default;
$--color-danger-light-9: mix($--color-whites, $--color-danger, 90%) !default; $--color-danger-light-9: mix($--color-whites, $--color-danger, 90%) !default;
$--bg-topBar: #ffffff; $--bg-topBar: #ffffff;
$--bg-menuBar: #29384d; $--bg-menuBar: #29384d;
$--bg-columnsMenuBar: #6bb4ff;
$--bg-topBarColor: #606266; $--bg-topBarColor: #606266;
$--bg-menuBarColor: #e6e6e6; $--bg-menuBarColor: #e6e6e6;
$--bg-columnsMenuBarColor: #e6e6e6;
/* 赋值给:root /* 赋值给:root
------------------------------- */ ------------------------------- */
@ -120,6 +122,8 @@ $--bg-menuBarColor: #e6e6e6;
--color-danger-light-9: #{$--color-danger-light-9}; --color-danger-light-9: #{$--color-danger-light-9};
--bg-topBar: #{$--bg-topBar}; --bg-topBar: #{$--bg-topBar};
--bg-menuBar: #{$--bg-menuBar}; --bg-menuBar: #{$--bg-menuBar};
--bg-columnsMenuBar: #{$--bg-columnsMenuBar};
--bg-topBarColor: #{$--bg-topBarColor}; --bg-topBarColor: #{$--bg-topBarColor};
--bg-menuBarColor: #{$--bg-menuBarColor}; --bg-menuBarColor: #{$--bg-menuBarColor};
--bg-columnsMenuBarColor: #{$--bg-columnsMenuBarColor};
} }

View File

@ -717,6 +717,13 @@
.el-menu--horizontal .el-menu .el-submenu.is-active > .el-submenu__title { .el-menu--horizontal .el-menu .el-submenu.is-active > .el-submenu__title {
color: set-color(primary); color: set-color(primary);
} }
.el-menu.el-menu--horizontal {
border-bottom: none !important;
}
.el-menu--horizontal > .el-menu-item,
.el-menu--horizontal > .el-submenu .el-submenu__title {
color: var(--bg-menuBarColor);
}
// 外部链接时 // 外部链接时
.el-menu-item a, .el-menu-item a,
.el-menu-item a:hover, .el-menu-item a:hover,

View File

@ -8,8 +8,10 @@ export default {
danger: "#f56c6c", danger: "#f56c6c",
topBar: "#ffffff", topBar: "#ffffff",
menuBar: "#29384d", menuBar: "#29384d",
columnsMenuBar: '#6BB4FF',
topBarColor: "#606266", topBarColor: "#606266",
menuBarColor: "#e6e6e6", menuBarColor: "#e6e6e6",
columnsMenuBarColor: '#e6e6e6',
isTopBarColorGradual: false, isTopBarColorGradual: false,
isMenuBarColorGradual: false, isMenuBarColorGradual: false,
isMenuBarColorHighlight: false, isMenuBarColorHighlight: false,
@ -29,5 +31,6 @@ export default {
isWartermark: false, isWartermark: false,
wartermarkText: 'small@小柒', wartermarkText: 'small@小柒',
tagsStyle: 'tagsStyleOne', tagsStyle: 'tagsStyleOne',
animation: 'slideRight' animation: 'slideRight',
layout: 'defaults'
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<el-aside :class="getThemeConfig.isCollapse ? 'layout-aside-width64' : 'layout-aside-width-default'"> <el-aside :class="setCollapseWidth">
<Logo v-if="getThemeConfig.isShowLogo" /> <Logo v-if="setShowLogo" />
<el-scrollbar class="flex-auto" ref="layoutAsideScrollbarRef"> <el-scrollbar class="flex-auto" ref="layoutAsideScrollbarRef">
<Vertical :menuList="menuList" /> <Vertical :menuList="menuList" />
</el-scrollbar> </el-scrollbar>
@ -8,7 +8,14 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { toRefs, reactive, computed, watch, getCurrentInstance } from "vue"; import {
toRefs,
reactive,
computed,
watch,
getCurrentInstance,
ref,
} from "vue";
import { useStore } from "/@/store/index.ts"; import { useStore } from "/@/store/index.ts";
import Logo from "/@/views/layout/logo/index.vue"; import Logo from "/@/views/layout/logo/index.vue";
import Vertical from "/@/views/layout/navMenu/vertical.vue"; import Vertical from "/@/views/layout/navMenu/vertical.vue";
@ -67,16 +74,50 @@ export default {
}, },
], ],
}); });
const getThemeConfig = computed(() => { // /
return store.state.themeConfig; const setCollapseWidth = computed(() => {
let { layout, isCollapse, menuBar } = store.state.themeConfig;
let asideBrColor =
menuBar === "#FFFFFF" ||
menuBar === "#FFF" ||
menuBar === "#fff" ||
menuBar === "#ffffff"
? "layout-el-aside-br-color"
: "";
if (layout === "columns") {
// 1px
if (isCollapse) {
return ["layout-aside-width1", asideBrColor];
} else {
return ["layout-aside-width-default", asideBrColor];
}
} else {
// 64px
if (isCollapse) {
return ["layout-aside-width64", asideBrColor];
} else {
return ["layout-aside-width-default", asideBrColor];
}
}
}); });
// / logo
const setShowLogo = computed(() => {
let { layout, isShowLogo } = store.state.themeConfig;
return (
(isShowLogo && layout === "defaults") ||
(isShowLogo && layout === "columns")
);
});
// themeConfig el-scrollbar
watch(store.state.themeConfig, (val) => { watch(store.state.themeConfig, (val) => {
if (val.isShowLogoChange !== val.isShowLogo) { if (val.isShowLogoChange !== val.isShowLogo) {
if (!proxy.$refs.layoutAsideScrollbarRef) return false;
proxy.$refs.layoutAsideScrollbarRef.update(); proxy.$refs.layoutAsideScrollbarRef.update();
} }
}); });
return { return {
getThemeConfig, setCollapseWidth,
setShowLogo,
...toRefs(state), ...toRefs(state),
}; };
}, },

View File

@ -0,0 +1,131 @@
<template>
<div class="layout-columns-aside">
<el-scrollbar>
<ul>
<li v-for="(v,k) in columnsAsideList" :key="k" @click="onColumnsAsideDown(v,k)"
:ref="el => { if (el) columnsAsideOffsetTopRefs[k] = el }" :class="{'layout-columns-active': liIndex === k}">
<div class="layout-columns-aside-li-box">
<template v-if="!v.meta.isLink">
<i :class="v.meta.icon"></i>
<div class="layout-columns-aside-li-box-title">
{{v.meta.title}}
</div>
</template>
<template v-else>
<a :href="v.meta.isLink" target="_block">
<i :class="v.meta.icon"></i>
<div class="layout-columns-aside-li-box-title">
{{v.meta.title}}
</div>
</a>
</template>
</div>
</li>
<div class="layout-columns-aside-active" ref="columnsAsideActiveRef"></div>
</ul>
</el-scrollbar>
</div>
</template>
<script lang="ts">
import { reactive, toRefs, ref } from "vue";
export default {
name: "layoutColumnsAside",
setup() {
const columnsAsideOffsetTopRefs = ref([]);
const columnsAsideActiveRef = ref();
const state = reactive({
columnsAsideList: [
{
path: "/home",
meta: {
title: "首页",
icon: "el-icon-medal-1",
},
},
{
path: "/home",
meta: {
title: "小米",
icon: "el-icon-trophy",
},
},
{
path: "/home",
meta: {
title: "谷歌",
icon: "el-icon-basketball",
isLink: "https://www.ele.me",
},
},
{
path: "/home",
meta: {
title: "苹果",
icon: "el-icon-coffee-cup",
},
},
],
liIndex: 0,
});
//
const onColumnsAsideDown = (v: Object, k: number) => {
state.liIndex = k;
columnsAsideActiveRef.value.style.top = `${
columnsAsideOffsetTopRefs.value[k].offsetTop + 3
}px`;
};
return {
columnsAsideOffsetTopRefs,
columnsAsideActiveRef,
onColumnsAsideDown,
...toRefs(state),
};
},
};
</script>
<style scoped lang="scss">
.layout-columns-aside {
width: 64px;
height: 100%;
background: var(--bg-columnsMenuBar);
ul {
position: relative;
li {
color: var(--bg-columnsMenuBarColor);
width: 100%;
height: 50px;
text-align: center;
display: flex;
cursor: pointer;
position: relative;
z-index: 1;
.layout-columns-aside-li-box {
margin: auto;
}
a {
text-decoration: none;
color: var(--bg-columnsMenuBarColor);
}
}
.layout-columns-active {
color: #ffffff;
transition: 0.3s ease-in-out;
}
.layout-columns-aside-active {
background: var(--color-primary);
color: #ffffff;
position: absolute;
left: 50%;
top: 2px;
height: 44px;
width: 58px;
transform: translateX(-50%);
z-index: 0;
transition: 0.3s ease-in-out;
border-radius: 5px;
}
}
}
</style>

View File

@ -1,5 +1,5 @@
<template> <template>
<el-header :height="getThemeConfig.isTagsview ? '84px' : '50px'"> <el-header :height="setHeaderHeight">
<NavBarsIndex /> <NavBarsIndex />
</el-header> </el-header>
</template> </template>
@ -13,11 +13,14 @@ export default {
components: { NavBarsIndex }, components: { NavBarsIndex },
setup() { setup() {
const store = useStore(); const store = useStore();
const getThemeConfig = computed(() => { // header
return store.state.themeConfig; const setHeaderHeight = computed(() => {
let { isTagsview, layout } = store.state.themeConfig;
if (isTagsview && layout !== "classic") return "84px";
else return "50px";
}); });
return { return {
getThemeConfig, setHeaderHeight,
}; };
}, },
}; };

View File

@ -1,7 +1,7 @@
<template> <template>
<el-main> <el-main>
<el-scrollbar class="layout-scrollbar" :style="{minHeight: `calc(100vh - ${headerHeight}`}" <el-scrollbar class="layout-scrollbar" ref="layoutScrollbarRef"
ref="layoutScrollbarRef"> :style="{minHeight: `calc(100vh - ${headerHeight}`}">
<router-view v-slot="{ Component }"> <router-view v-slot="{ Component }">
<transition :name="setTransitionName" mode="out-in"> <transition :name="setTransitionName" mode="out-in">
<div :key="key"> <div :key="key">
@ -39,6 +39,7 @@ export default defineComponent({
transitionName: "slide-right", transitionName: "slide-right",
headerHeight: "84px", headerHeight: "84px",
}); });
//
const setTransitionName = computed(() => { const setTransitionName = computed(() => {
let { animation } = store.state.themeConfig; let { animation } = store.state.themeConfig;
if (animation === "slideRight") if (animation === "slideRight")
@ -48,13 +49,17 @@ export default defineComponent({
else if (animation === "opacitys") else if (animation === "opacitys")
return (state.transitionName = "opacitys"); return (state.transitionName = "opacitys");
}); });
//
const getThemeConfig = computed(() => { const getThemeConfig = computed(() => {
return store.state.themeConfig; return store.state.themeConfig;
}); });
// key
const key = computed(() => route.path); const key = computed(() => route.path);
// themeConfig el-scrollbar
watch(store.state.themeConfig, (val) => { watch(store.state.themeConfig, (val) => {
state.headerHeight = val.isTagsview ? "84px" : "50px"; state.headerHeight = val.isTagsview ? "84px" : "50px";
if (val.isFixedHeaderChange !== val.isFixedHeader) { if (val.isFixedHeaderChange !== val.isFixedHeader) {
if (!proxy.$refs.layoutScrollbarRef) return false;
proxy.$refs.layoutScrollbarRef.update(); proxy.$refs.layoutScrollbarRef.update();
} }
}); });

View File

@ -1,11 +1,50 @@
<template> <template>
<Defaults /> <Defaults v-if="getThemeConfig.layout === 'defaults'" />
<Classic v-else-if="getThemeConfig.layout === 'classic'" />
<Transverse v-else-if="getThemeConfig.layout === 'transverse'" />
<Columns v-else-if="getThemeConfig.layout === 'columns'" />
<Setings ref="setingsRef" />
</template> </template>
<script lang="ts"> <script lang="ts">
import Defaults from "/@/views/layout/defaults.vue"; import {
computed,
ref,
getCurrentInstance,
onBeforeMount,
onUnmounted,
} from "vue";
import { useStore } from "/@/store/index.ts";
import Defaults from "/@/views/layout/main/defaults.vue";
import Classic from "/@/views/layout/main/classic.vue";
import Transverse from "/@/views/layout/main/transverse.vue";
import Columns from "/@/views/layout/main/columns.vue";
import Setings from "/@/views/layout/navBars/breadcrumb/setings.vue";
export default { export default {
name: "layout", name: "layout",
components: { Defaults }, components: { Defaults, Classic, Transverse, Columns, Setings },
setup() {
const { proxy } = getCurrentInstance();
const setingsRef = ref();
const store = useStore();
const getThemeConfig = computed(() => {
return store.state.themeConfig;
});
const openSetingsDrawer = () => {
setingsRef.value.openDrawer();
};
onBeforeMount(() => {
proxy.mittBus.on("openSetingsDrawer", () => {
openSetingsDrawer();
});
});
onUnmounted(() => {
proxy.mittBus.off("openSetingsDrawer", () => {});
});
return {
setingsRef,
getThemeConfig,
};
},
}; };
</script> </script>

View File

@ -1,22 +1,34 @@
<template> <template>
<div class="layout-logo" v-if="!getThemeConfig.isCollapse">vue-admin-wonderful</div> <div class="layout-logo" v-if="setShowLogo" @click="onThemeConfigChange">
<div class="layout-logo-size" v-else> <span>vue-admin-wonderful</span>
</div>
<div class="layout-logo-size" v-else @click="onThemeConfigChange">
<img src="/@/assets/logo-docs-mini.svg" class="layout-logo-size-img" /> <img src="/@/assets/logo-docs-mini.svg" class="layout-logo-size-img" />
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed } from "vue"; import { computed, getCurrentInstance } from "vue";
import { useStore } from "/@/store/index.ts"; import { useStore } from "/@/store/index.ts";
export default { export default {
name: "layoutLogo", name: "layoutLogo",
setup() { setup() {
const { proxy } = getCurrentInstance();
const store = useStore(); const store = useStore();
const getThemeConfig = computed(() => { // logo classic logo
return store.state.themeConfig; const setShowLogo = computed(() => {
let { isCollapse, layout } = store.state.themeConfig;
return !isCollapse || layout === "classic";
}); });
// logo /
const onThemeConfigChange = () => {
if (store.state.themeConfig.layout === "transverse") return false;
proxy.mittBus.emit("onMenuClick");
store.state.themeConfig.isCollapse = !store.state.themeConfig.isCollapse;
};
return { return {
getThemeConfig, setShowLogo,
onThemeConfigChange,
}; };
}, },
}; };
@ -24,23 +36,36 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.layout-logo { .layout-logo {
height: 50px; width: 220px;
height: 49px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-shadow: rgb(0 21 41 / 3%) 0px 1px 4px; box-shadow: rgb(0 21 41 / 3%) 0px 1px 4px;
color: var(--color-primary); color: var(--color-primary);
font-size: 16px; font-size: 16px;
cursor: pointer;
animation: logoAnimation 0.3s ease-in-out; animation: logoAnimation 0.3s ease-in-out;
&:hover {
span {
color: var(--color-primary-light-2);
}
}
} }
.layout-logo-size { .layout-logo-size {
width: 100%; width: 100%;
height: 50px; height: 50px;
display: flex; display: flex;
cursor: pointer;
animation: logoAnimation 0.3s ease-in-out; animation: logoAnimation 0.3s ease-in-out;
&-img { &-img {
width: 30px; width: 30px;
margin: auto; margin: auto;
} }
&:hover {
img {
animation: logoAnimation 0.3s ease-in-out;
}
}
} }
</style> </style>

View File

@ -0,0 +1,23 @@
<template>
<el-container class="layout-container flex-center">
<Header />
<el-container class="layout-mian-height-50">
<Aside />
<div class="flex-center">
<TagsView />
<Main />
</div>
</el-container>
</el-container>
</template>
<script>
import Aside from '/@/views/layout/component/aside.vue';
import Header from '/@/views/layout/component/header.vue';
import Main from '/@/views/layout/component/main.vue';
import TagsView from "/@/views/layout/navBars/tagsView/tagsView.vue";
export default {
name: 'layoutClassic',
components: { Aside, Header, Main, TagsView }
}
</script>

View File

@ -0,0 +1,37 @@
<template>
<el-container class="layout-container">
<ColumnsAside />
<div style="flex:1;display: flex;">
<Aside />
<el-container class="flex-center">
<Header v-if="isFixedHeader" />
<el-scrollbar>
<Header v-if="!isFixedHeader" />
<Main />
</el-scrollbar>
</el-container>
</div>
</el-container>
</template>
<script>
import { computed } from 'vue'
import { useStore } from "/@/store/index.ts";
import Aside from '/@/views/layout/component/aside.vue';
import Header from '/@/views/layout/component/header.vue';
import Main from '/@/views/layout/component/main.vue';
import ColumnsAside from '/@/views/layout/component/columnsAside.vue';
export default {
name: 'layoutColumns',
components: { Aside, Header, Main, ColumnsAside },
setup() {
const store = useStore();
const isFixedHeader = computed(() => {
return store.state.themeConfig.isFixedHeader;
});
return {
isFixedHeader
}
}
}
</script>

View File

@ -9,39 +9,23 @@
</el-scrollbar> </el-scrollbar>
</el-container> </el-container>
</el-container> </el-container>
<Setings ref="setingsRef" />
</template> </template>
<script> <script>
import { computed, ref, getCurrentInstance, onBeforeMount, onUnmounted } from 'vue' import { computed } from 'vue'
import { useStore } from "/@/store/index.ts"; import { useStore } from "/@/store/index.ts";
import Aside from '/@/views/layout/component/aside.vue'; import Aside from '/@/views/layout/component/aside.vue';
import Header from '/@/views/layout/component/header.vue'; import Header from '/@/views/layout/component/header.vue';
import Main from '/@/views/layout/component/main.vue'; import Main from '/@/views/layout/component/main.vue';
import Setings from "/@/views/layout/navBars/breadcrumb/setings.vue";
export default { export default {
name: 'layoutFashion', name: 'layoutDefaults',
components: { Aside, Header, Main, Setings }, components: { Aside, Header, Main },
setup() { setup() {
const { proxy } = getCurrentInstance();
const store = useStore(); const store = useStore();
const setingsRef = ref();
const isFixedHeader = computed(() => { const isFixedHeader = computed(() => {
return store.state.themeConfig.isFixedHeader; return store.state.themeConfig.isFixedHeader;
}); });
const openSetingsDrawer = () => {
setingsRef.value.openDrawer();
}
onBeforeMount(() => {
proxy.mittBus.on("openSetingsDrawer", () => {
openSetingsDrawer();
});
});
onUnmounted(() => {
proxy.mittBus.off("openSetingsDrawer", () => { });
});
return { return {
setingsRef,
isFixedHeader isFixedHeader
} }
} }

View File

@ -0,0 +1,17 @@
<template>
<el-container class="layout-container flex-center">
<Header />
<Main />
</el-container>
</template>
<script>
import Aside from '/@/views/layout/component/aside.vue';
import Header from '/@/views/layout/component/header.vue';
import Main from '/@/views/layout/component/main.vue';
import TagsView from "/@/views/layout/navBars/tagsView/tagsView.vue";
export default {
name: 'layoutTransverse',
components: { Aside, Header, Main, TagsView }
}
</script>

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="layout-navbars-breadcrumb"> <div class="layout-navbars-breadcrumb" v-show="getThemeConfig.isBreadcrumb">
<i class="layout-navbars-breadcrumb-icon" :class="getThemeConfig.isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'" <i class="layout-navbars-breadcrumb-icon" :class="getThemeConfig.isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'"
@click="onThemeConfigChange"></i> @click="onThemeConfigChange"></i>
<el-breadcrumb v-show="getThemeConfig.isBreadcrumb"> <el-breadcrumb>
<transition-group name="breadcrumb" mode="out-in"> <transition-group name="breadcrumb" mode="out-in">
<el-breadcrumb-item v-for="(v,k) in breadcrumbList" :key="v.meta.title"> <el-breadcrumb-item v-for="(v,k) in breadcrumbList" :key="v.meta.title">
<span v-if="k === breadcrumbList.length - 1" class="layout-navbars-breadcrumb-span">{{v.meta.title}}</span> <span v-if="k === breadcrumbList.length - 1" class="layout-navbars-breadcrumb-span">{{v.meta.title}}</span>
@ -70,6 +70,7 @@ export default {
height: inherit; height: inherit;
display: flex; display: flex;
align-items: center; align-items: center;
padding-left: 15px;
.layout-navbars-breadcrumb-icon { .layout-navbars-breadcrumb-icon {
cursor: pointer; cursor: pointer;
font-size: 18px; font-size: 18px;

View File

@ -1,16 +1,82 @@
<template> <template>
<div class="layout-navbars-breadcrumb-index"> <div class="layout-navbars-breadcrumb-index">
<Logo
v-if="getThemeConfig.isShowLogo && getThemeConfig.layout === 'classic' || getThemeConfig.isShowLogo && getThemeConfig.layout === 'transverse'" />
<Breadcrumb /> <Breadcrumb />
<Horizontal :menuList="menuList" v-if="getThemeConfig.layout === 'transverse'" />
<User /> <User />
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, reactive, toRefs } from "vue";
import { useStore } from "/@/store/index.ts";
import Breadcrumb from "/@/views/layout/navBars/breadcrumb/breadcrumb.vue"; import Breadcrumb from "/@/views/layout/navBars/breadcrumb/breadcrumb.vue";
import User from "/@/views/layout/navBars/breadcrumb/user.vue"; import User from "/@/views/layout/navBars/breadcrumb/user.vue";
import Logo from "/@/views/layout/logo/index.vue";
import Horizontal from "/@/views/layout/navMenu/horizontal.vue";
export default { export default {
name: "layoutBreadcrumbIndex", name: "layoutBreadcrumbIndex",
components: { Breadcrumb, User }, components: { Breadcrumb, User, Logo, Horizontal },
setup() {
const store = useStore();
const getThemeConfig = computed(() => {
return store.state.themeConfig;
});
const state = reactive({
menuList: [
{
path: "/home",
meta: {
title: "首页",
icon: "el-icon-s-home",
},
children: [
{
path: "/home",
meta: {
title: "微软",
icon: "el-icon-s-flag",
},
},
{
path: "/docs",
meta: {
title: "文档",
icon: "el-icon-s-flag",
},
},
{
path: "/docs1",
meta: {
title: "文档1",
icon: "el-icon-s-flag",
},
},
],
},
{
path: "/docs2",
meta: {
title: "文档2",
icon: "el-icon-s-management",
isLink: "https://www.ele.me",
},
},
{
path: "/docs3",
meta: {
title: "文档3",
icon: "el-icon-s-management",
},
},
],
});
return {
getThemeConfig,
...toRefs(state),
};
},
}; };
</script> </script>
@ -19,7 +85,8 @@ export default {
height: 50px; height: 50px;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0 15px; padding-right: 15px;
background: var(--bg-topBar); background: var(--bg-topBar);
overflow: hidden;
} }
</style> </style>

View File

@ -55,6 +55,14 @@
</el-color-picker> </el-color-picker>
</div> </div>
</div> </div>
<div class="layout-breadcrumb-seting-bar-flex">
<div class="layout-breadcrumb-seting-bar-flex-label">分栏菜单背景</div>
<div class="layout-breadcrumb-seting-bar-flex-value">
<el-color-picker v-model="getThemeConfig.columnsMenuBar" size="small"
@change="onBgColorPickerChange('columnsMenuBar')">
</el-color-picker>
</div>
</div>
<div class="layout-breadcrumb-seting-bar-flex"> <div class="layout-breadcrumb-seting-bar-flex">
<div class="layout-breadcrumb-seting-bar-flex-label">顶栏默认字体颜色</div> <div class="layout-breadcrumb-seting-bar-flex-label">顶栏默认字体颜色</div>
<div class="layout-breadcrumb-seting-bar-flex-value"> <div class="layout-breadcrumb-seting-bar-flex-value">
@ -71,6 +79,14 @@
</el-color-picker> </el-color-picker>
</div> </div>
</div> </div>
<div class="layout-breadcrumb-seting-bar-flex">
<div class="layout-breadcrumb-seting-bar-flex-label">分栏菜单默认字体颜色</div>
<div class="layout-breadcrumb-seting-bar-flex-value">
<el-color-picker v-model="getThemeConfig.columnsMenuBarColor" size="small"
@change="onBgColorPickerChange('columnsMenuBarColor')">
</el-color-picker>
</div>
</div>
<div class="layout-breadcrumb-seting-bar-flex mt10"> <div class="layout-breadcrumb-seting-bar-flex mt10">
<div class="layout-breadcrumb-seting-bar-flex-label">顶栏背景渐变</div> <div class="layout-breadcrumb-seting-bar-flex-label">顶栏背景渐变</div>
<div class="layout-breadcrumb-seting-bar-flex-value"> <div class="layout-breadcrumb-seting-bar-flex-value">
@ -205,23 +221,25 @@
<el-divider content-position="left">布局切换</el-divider> <el-divider content-position="left">布局切换</el-divider>
<div class="layout-drawer-content-flex"> <div class="layout-drawer-content-flex">
<!-- defaults 布局 --> <!-- defaults 布局 -->
<div class="layout-drawer-content-item"> <div class="layout-drawer-content-item" @click="onSetLayout('defaults')">
<section class="el-container drawer-layout-active el-circular"> <section class="el-container el-circular"
:class="{'drawer-layout-active': getThemeConfig.layout === 'defaults'}">
<aside class="el-aside" style="width: 20px"></aside> <aside class="el-aside" style="width: 20px"></aside>
<section class="el-container is-vertical"> <section class="el-container is-vertical">
<header class="el-header" style="height: 10px"></header> <header class="el-header" style="height: 10px"></header>
<main class="el-main"></main> <main class="el-main"></main>
</section> </section>
</section> </section>
<div class="layout-tips-warp-active layout-tips-warp"> <div class="layout-tips-warp" :class="{'layout-tips-warp-active': getThemeConfig.layout === 'defaults'}">
<div class="layout-tips-box"> <div class="layout-tips-box">
<p class="layout-tips-txt">默认</p> <p class="layout-tips-txt">默认</p>
</div> </div>
</div> </div>
</div> </div>
<!-- classic 布局 --> <!-- classic 布局 -->
<div class="layout-drawer-content-item"> <div class="layout-drawer-content-item" @click="onSetLayout('classic')">
<section class="el-container is-vertical el-circular"> <section class="el-container is-vertical el-circular"
:class="{'drawer-layout-active': getThemeConfig.layout === 'classic'}">
<header class="el-header" style="height: 10px"></header> <header class="el-header" style="height: 10px"></header>
<section class="el-container"> <section class="el-container">
<aside class="el-aside" style="width: 20px"></aside> <aside class="el-aside" style="width: 20px"></aside>
@ -230,15 +248,16 @@
</section> </section>
</section> </section>
</section> </section>
<div class="layout-tips-warp"> <div class="layout-tips-warp" :class="{'layout-tips-warp-active': getThemeConfig.layout === 'classic'}">
<div class="layout-tips-box"> <div class="layout-tips-box">
<p class="layout-tips-txt">经典</p> <p class="layout-tips-txt">经典</p>
</div> </div>
</div> </div>
</div> </div>
<!-- transverse 布局 --> <!-- transverse 布局 -->
<div class="layout-drawer-content-item"> <div class="layout-drawer-content-item" @click="onSetLayout('transverse')">
<section class="el-container is-vertical el-circular"> <section class="el-container is-vertical el-circular"
:class="{'drawer-layout-active': getThemeConfig.layout === 'transverse'}">
<header class="el-header" style="height: 10px"></header> <header class="el-header" style="height: 10px"></header>
<section class="el-container"> <section class="el-container">
<section class="el-container is-vertical"> <section class="el-container is-vertical">
@ -246,15 +265,16 @@
</section> </section>
</section> </section>
</section> </section>
<div class="layout-tips-warp"> <div class="layout-tips-warp" :class="{'layout-tips-warp-active': getThemeConfig.layout === 'transverse'}">
<div class="layout-tips-box"> <div class="layout-tips-box">
<p class="layout-tips-txt">横向</p> <p class="layout-tips-txt">横向</p>
</div> </div>
</div> </div>
</div> </div>
<!-- columns 布局 --> <!-- columns 布局 -->
<div class="layout-drawer-content-item"> <div class="layout-drawer-content-item" @click="onSetLayout('columns')">
<section class="el-container el-circular"> <section class="el-container el-circular"
:class="{'drawer-layout-active': getThemeConfig.layout === 'columns'}">
<aside class="el-aside-dark" style="width: 10px"></aside> <aside class="el-aside-dark" style="width: 10px"></aside>
<aside class="el-aside" style="width: 20px"></aside> <aside class="el-aside" style="width: 20px"></aside>
<section class="el-container is-vertical"> <section class="el-container is-vertical">
@ -262,7 +282,7 @@
<main class="el-main"></main> <main class="el-main"></main>
</section> </section>
</section> </section>
<div class="layout-tips-warp"> <div class="layout-tips-warp" :class="{'layout-tips-warp-active': getThemeConfig.layout === 'columns'}">
<div class="layout-tips-box"> <div class="layout-tips-box">
<p class="layout-tips-txt">分栏</p> <p class="layout-tips-txt">分栏</p>
</div> </div>
@ -346,6 +366,7 @@ export default defineComponent({
const setGraduaFun = (el: string, bool: boolean, color: string) => { const setGraduaFun = (el: string, bool: boolean, color: string) => {
nextTick(() => { nextTick(() => {
let els = document.querySelector(el); let els = document.querySelector(el);
if (!els) return false;
if (bool) if (bool)
els.setAttribute( els.setAttribute(
"style", "style",
@ -414,7 +435,63 @@ export default defineComponent({
if (getThemeConfig.value.isWartermark) if (getThemeConfig.value.isWartermark)
Watermark.set(getThemeConfig.value.wartermarkText); Watermark.set(getThemeConfig.value.wartermarkText);
}; };
const onSetLayout = (layout: string) => {
if (getThemeConfig.value.layout === layout) return false;
getThemeConfig.value.layout = layout;
getThemeConfig.value.isDrawer = false;
initLayoutStyle();
};
const initLayoutStyle = () => {
console.log(getThemeConfig);
if (getThemeConfig.value.layout === "classic") {
getThemeConfig.value.isShowLogo = true;
getThemeConfig.value.isBreadcrumb = false;
getThemeConfig.value.menuBar = "#FFFFFF";
getThemeConfig.value.menuBarColor = "#606266";
getThemeConfig.value.topBar = "#ffffff";
getThemeConfig.value.topBarColor = "#606266";
onBgColorPickerChange("menuBar");
onBgColorPickerChange("menuBarColor");
onBgColorPickerChange("topBar");
onBgColorPickerChange("topBarColor");
} else if (getThemeConfig.value.layout === "transverse") {
getThemeConfig.value.isShowLogo = true;
getThemeConfig.value.isBreadcrumb = false;
getThemeConfig.value.isTagsview = false;
getThemeConfig.value.menuBarColor = "#FFFFFF";
getThemeConfig.value.topBar = "#545c64";
getThemeConfig.value.topBarColor = "#FFFFFF";
onBgColorPickerChange("topBar");
onBgColorPickerChange("menuBarColor");
onBgColorPickerChange("topBarColor");
} else if (getThemeConfig.value.layout === "columns") {
getThemeConfig.value.isShowLogo = true;
getThemeConfig.value.isBreadcrumb = true;
getThemeConfig.value.isTagsview = true;
getThemeConfig.value.menuBar = "#FFFFFF";
getThemeConfig.value.menuBarColor = "#606266";
getThemeConfig.value.topBar = "#ffffff";
getThemeConfig.value.topBarColor = "#606266";
onBgColorPickerChange("menuBar");
onBgColorPickerChange("menuBarColor");
onBgColorPickerChange("topBar");
onBgColorPickerChange("topBarColor");
} else {
getThemeConfig.value.isShowLogo = false;
getThemeConfig.value.isBreadcrumb = true;
getThemeConfig.value.isTagsview = true;
getThemeConfig.value.menuBar = "#545c64";
getThemeConfig.value.menuBarColor = "#FFFFFF";
getThemeConfig.value.topBar = "#FFFFFF";
getThemeConfig.value.topBarColor = "#606266";
onBgColorPickerChange("menuBar");
onBgColorPickerChange("menuBarColor");
onBgColorPickerChange("topBar");
onBgColorPickerChange("topBarColor");
}
};
onBeforeMount(() => { onBeforeMount(() => {
initLayoutStyle();
proxy.mittBus.on("onMenuClick", () => { proxy.mittBus.on("onMenuClick", () => {
onMenuBarHighlightChange(); onMenuBarHighlightChange();
}); });
@ -438,6 +515,7 @@ export default defineComponent({
onAddFilterChange, onAddFilterChange,
onWartermarkChange, onWartermarkChange,
onWartermarkTextInput, onWartermarkTextInput,
onSetLayout,
}; };
}, },
}); });

View File

@ -48,10 +48,13 @@ export default {
.layout-navbars-breadcrumb-user { .layout-navbars-breadcrumb-user {
display: flex; display: flex;
align-items: center; align-items: center;
flex: 1;
justify-content: flex-end;
&-link { &-link {
height: 100%; height: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
white-space: nowrap;
&-photo { &-photo {
width: 25px; width: 25px;
height: 25px; height: 25px;

View File

@ -1,16 +1,28 @@
<template> <template>
<div class="layout-navbars-container"> <div class="layout-navbars-container">
<BreadcrumbIndex /> <BreadcrumbIndex />
<TagsView /> <TagsView
v-if="getThemeConfig.layout === 'defaults' || getThemeConfig.layout === 'transverse' || getThemeConfig.layout === 'columns'" />
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed } from "vue";
import { useStore } from "/@/store/index.ts";
import BreadcrumbIndex from "/@/views/layout/navBars/breadcrumb/index.vue"; import BreadcrumbIndex from "/@/views/layout/navBars/breadcrumb/index.vue";
import TagsView from "/@/views/layout/navBars/tagsView/tagsView.vue"; import TagsView from "/@/views/layout/navBars/tagsView/tagsView.vue";
export default { export default {
name: "layoutNavBars", name: "layoutNavBars",
components: { BreadcrumbIndex, TagsView }, components: { BreadcrumbIndex, TagsView },
setup() {
const store = useStore();
const getThemeConfig = computed(() => {
return store.state.themeConfig;
});
return {
getThemeConfig,
};
},
}; };
</script> </script>

View File

@ -1,5 +1,6 @@
<template> <template>
<div class="layout-navbars-tagsview" v-show="getThemeConfig.isTagsview"> <div class="layout-navbars-tagsview" :class="{'layout-navbars-tagsview-shadow': getThemeConfig.layout === 'classic'}"
v-show="getThemeConfig.isTagsview">
<Scroll ref="scrollRef"> <Scroll ref="scrollRef">
<ul class="layout-navbars-tagsview-ul" :class="setTagsStyle"> <ul class="layout-navbars-tagsview-ul" :class="setTagsStyle">
<li v-for="(v,k) in arr2" :key="k" class="layout-navbars-tagsview-ul-li" :class="{'is-active':isActive(v.path)}" <li v-for="(v,k) in arr2" :key="k" class="layout-navbars-tagsview-ul-li" :class="{'is-active':isActive(v.path)}"
@ -308,4 +309,7 @@ export default {
} }
} }
} }
.layout-navbars-tagsview-shadow {
box-shadow: rgb(0 21 41 / 4%) 0px 1px 4px;
}
</style> </style>

View File

@ -0,0 +1,60 @@
<template>
<el-menu router :default-active="defaultActive" background-color="transparent" mode="horizontal">
<template v-for="val in menuList">
<el-submenu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
<template #title>
<i :class="val.meta.icon ? val.meta.icon : ''"></i>
<span>{{ val.meta.title }}</span>
</template>
<SubItem :chil="val.children" />
</el-submenu>
<el-menu-item :index="val.path" :key="val.path" v-else>
<i :class="val.meta.icon ? val.meta.icon : ''"></i>
<template #title v-if="!val.meta.isLink">{{ val.meta.title }}</template>
<template #title v-else><a :href="val.meta.isLink" target="_blank">{{ val.meta.title }}</a></template>
</el-menu-item>
</template>
</el-menu>
</template>
<script lang="ts">
import {
toRefs,
reactive,
computed,
defineComponent,
getCurrentInstance,
} from "vue";
import { useRoute, onBeforeRouteUpdate } from "vue-router";
import SubItem from "/@/views/layout/navMenu/subItem.vue";
export default defineComponent({
name: "navMenuHorizontal",
components: { SubItem },
props: {
menuList: {
type: Array,
default() {
return [];
},
},
},
setup(props) {
const { proxy } = getCurrentInstance();
const route = useRoute();
const state = reactive({
defaultActive: route.path,
});
const menuList = computed(() => {
return props.menuList;
});
onBeforeRouteUpdate((to) => {
state.defaultActive = to.path;
proxy.mittBus.emit("onMenuClick");
});
return {
menuList,
...toRefs(state),
};
},
});
</script>