初始化拉取,原文件名:admin-plus-webpack5
Some checks failed
Call HTTPS API / build (push) Has been cancelled

This commit is contained in:
2025-12-26 20:43:10 +08:00
parent 7c68ec3a42
commit 3e2da1115e
420 changed files with 75413 additions and 2 deletions

View File

@@ -0,0 +1,78 @@
<!--分栏布局 -->
<script lang="ts" setup>
import { useSettingsStore } from '@/store/modules/settings'
defineProps({
collapse: {
type: Boolean,
default() {
return false
},
},
fixedHeader: {
type: Boolean,
default() {
return true
},
},
showTabs: {
type: Boolean,
default() {
return true
},
},
})
const settingsStore = useSettingsStore()
const { theme } = storeToRefs(settingsStore)
</script>
<template>
<div
class="vab-layout-column"
:class="{
fixed: fixedHeader,
'no-tabs-bar': !showTabs,
}"
>
<vab-column-bar />
<div
class="vab-main"
:class="{
['vab-main-' + theme.columnStyle]: true,
'is-collapse-main': collapse,
}"
>
<div
class="vab-layout-header"
:class="{
'fixed-header': fixedHeader,
}"
>
<vab-nav />
<vab-tabs v-show="showTabs" />
</div>
<vab-app-main />
</div>
</div>
</template>
<style lang="scss" scoped>
.vab-layout-column {
.vab-main {
&.is-collapse-main {
&.vab-main-horizontal {
margin-left: $base-left-menu-width-min * 1.3;
:deep() {
.fixed-header {
width: calc(
100% - #{$base-left-menu-width-min} * 1.3
);
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,88 @@
<!--常规布局 -->
<script lang="ts" setup>
defineProps({
collapse: {
type: Boolean,
default() {
return false
},
},
fixedHeader: {
type: Boolean,
default() {
return true
},
},
showTabs: {
type: Boolean,
default() {
return true
},
},
device: {
type: String,
default() {
return 'desktop'
},
},
})
</script>
<template>
<div
class="vab-layout-common"
:class="{
fixed: fixedHeader,
'no-tabs-bar': !showTabs,
}"
>
<div
class="vab-layout-header"
:class="{
'fixed-header': fixedHeader,
}"
>
<vab-header layout="common" />
<div>
<vab-side-bar layout="common" />
<div
v-show="showTabs"
class="vab-main"
:class="{
'is-collapse-main': collapse,
}"
>
<vab-tabs layout="common" />
</div>
</div>
</div>
<div
class="vab-main main-padding"
:class="{
'is-collapse-main': collapse,
}"
>
<vab-app-main />
</div>
</div>
</template>
<style lang="scss" scoped>
.vab-layout-common {
:deep() {
.vab-tabs-content {
width: calc(
100% - 60px - #{$base-font-size-default} -
#{$base-padding} - 2px
) !important;
}
.vab-header {
.vab-main {
width: 100%;
margin: auto $base-margin;
}
}
}
}
</style>

View File

@@ -0,0 +1,58 @@
<!--综合布局 -->
<script lang="ts" setup>
defineProps({
collapse: {
type: Boolean,
default() {
return false
},
},
fixedHeader: {
type: Boolean,
default() {
return true
},
},
showTabs: {
type: Boolean,
default() {
return true
},
},
device: {
type: String,
default() {
return 'desktop'
},
},
})
</script>
<template>
<div
class="vab-layout-comprehensive"
:class="{
fixed: fixedHeader,
'no-tabs-bar': !showTabs,
}"
>
<vab-side-bar layout="comprehensive" />
<div
class="vab-main"
:class="{
'is-collapse-main': collapse,
}"
>
<div
class="vab-layout-header"
:class="{
'fixed-header': fixedHeader,
}"
>
<vab-nav layout="comprehensive" />
<vab-tabs v-show="showTabs" />
</div>
<vab-app-main />
</div>
</div>
</template>

View File

@@ -0,0 +1,98 @@
<!--浮动布局 -->
<script lang="ts" setup>
import { useSettingsStore } from '@/store/modules/settings'
defineProps({
fixedHeader: {
type: Boolean,
default() {
return true
},
},
showTabs: {
type: Boolean,
default() {
return true
},
},
})
const settingsStore = useSettingsStore()
const { foldSideBar, openSideBar } = settingsStore
foldSideBar()
onUnmounted(() => {
openSideBar()
})
</script>
<template>
<div
class="vab-layout-float"
:class="{
fixed: fixedHeader,
'no-tabs-bar': !showTabs,
}"
>
<vab-side-bar layout="float" />
<div class="vab-main">
<div
class="vab-layout-header"
:class="{
'fixed-header': fixedHeader,
}"
>
<vab-nav layout="float" />
<vab-tabs v-show="showTabs" />
</div>
<vab-app-main />
</div>
</div>
</template>
<!--由于element-plus
bug使用teleported=false会导致多级路由无法显示故所有菜单必须生成至body下样式必须放到body下-->
<style lang="scss" scoped>
.vab-layout-float {
:deep() {
.vab-main {
margin-left: $base-left-menu-width-min !important;
.fixed-header {
width: $base-right-content-width-min !important;
}
}
.el-menu--collapse.el-menu li.el-sub-menu.is-active {
.el-sub-menu__title {
background-color: transparent !important;
}
> .el-sub-menu__title {
background-color: var(--el-color-primary) !important;
}
}
.vab-menu-children-height {
height: auto !important;
}
.el-menu {
&--vertical {
.el-menu--popup-right-start {
width: 335px !important;
.el-sub-menu__title,
.el-menu-item {
float: left;
width: 160px;
min-width: 160px;
margin: 0 0 5px 5px;
border-radius: $base-border-radius;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,83 @@
<!-- 横向布局 -->
<script lang="ts" setup>
defineProps({
collapse: {
type: Boolean,
default() {
return false
},
},
fixedHeader: {
type: Boolean,
default() {
return true
},
},
showTabs: {
type: Boolean,
default() {
return true
},
},
device: {
type: String,
default() {
return 'desktop'
},
},
})
</script>
<template>
<div
class="vab-layout-horizontal"
:class="{
fixed: fixedHeader,
'no-tabs-bar': !showTabs,
}"
>
<div
class="vab-layout-header"
:class="{
'fixed-header': fixedHeader,
}"
>
<vab-header layout="horizontal" />
<div
v-show="showTabs"
:class="{
'vab-tabs-horizontal': showTabs,
}"
>
<div class="vab-main">
<vab-tabs />
</div>
</div>
</div>
<div class="vab-main main-padding">
<vab-app-main />
</div>
</div>
</template>
<style lang="scss" scoped>
.vab-layout-horizontal {
:deep() {
.vab-main {
width: 92% !important;
margin: auto !important;
}
}
.vab-tabs-horizontal {
background: var(--el-color-white);
box-shadow: $base-box-shadow;
}
.vab-nav {
.fold-unfold {
display: none;
}
}
}
</style>

View File

@@ -0,0 +1,68 @@
<!-- 纵向布局 -->
<script lang="ts" setup>
import { useSettingsStore } from '@/store/modules/settings'
defineProps({
collapse: {
type: Boolean,
default() {
return false
},
},
fixedHeader: {
type: Boolean,
default() {
return true
},
},
showTabs: {
type: Boolean,
default() {
return true
},
},
device: {
type: String,
default() {
return 'desktop'
},
},
})
const settingsStore = useSettingsStore()
const { foldSideBar } = settingsStore
</script>
<template>
<div
class="vab-layout-vertical"
:class="{
fixed: fixedHeader,
'no-tabs-bar': !showTabs,
}"
>
<vab-side-bar />
<div
v-if="device === 'mobile' && !collapse"
class="v-modal"
@click="foldSideBar"
/>
<div
class="vab-main"
:class="{
'is-collapse-main': collapse,
}"
>
<div
class="vab-layout-header"
:class="{
'fixed-header': fixedHeader,
}"
>
<vab-nav />
<vab-tabs v-show="showTabs" />
</div>
<vab-app-main />
</div>
</div>
</template>

162
library/layouts/index.vue Normal file
View File

@@ -0,0 +1,162 @@
<template>
<div class="vue-admin-better-wrapper" :class="{ mobile }">
<component
:is="'vab-layout-' + theme.layout"
:collapse="collapse"
:device="device"
:fixed-header="theme.fixedHeader"
:show-tabs="theme.showTabs"
/>
<el-backtop target="#app" />
<!-- 主题组件放到layouts下防止主题切换导致主题组件重新加载 -->
<vab-theme-drawer />
<vab-theme-setting />
</div>
</template>
<script lang="ts">
import { useSettingsStore } from '@/store/modules/settings'
const imports = require.context('./', true, /\.vue$/)
const Components: any = {}
imports
.keys()
.filter((key) => key !== './index.vue')
.forEach((key) => {
Components[key.replace(/(\/|\.|index.vue)/g, '')] =
imports(key).default
})
export default defineComponent({
name: 'Layouts',
components: Components,
setup() {
const settingsStore = useSettingsStore()
const { device, collapse, theme } = storeToRefs(settingsStore)
const { toggleDevice, foldSideBar, openSideBar, updateTheme } =
settingsStore
const mobile = ref(false)
let oldLayout = theme.value.layout
const resizeBody = () => {
mobile.value =
document.body.getBoundingClientRect().width - 1 < 992
}
watch(mobile, (val) => {
if (val) {
oldLayout = theme.value.layout
foldSideBar()
} else openSideBar()
theme.value.layout = val ? 'vertical' : oldLayout
toggleDevice(val ? 'mobile' : 'desktop')
})
resizeBody()
updateTheme()
const cleanup = useEventListener('resize', () => {
resizeBody()
})
onUnmounted(() => {
if (mobile) theme.value.layout = oldLayout
cleanup()
})
return {
theme,
device,
mobile,
collapse,
foldSideBar,
openSideBar,
toggleDevice,
}
},
})
</script>
<style lang="scss" scoped>
.vue-admin-better-wrapper {
position: relative;
width: 100%;
height: 100%;
[class*='vab-layout-'] {
:deep() {
.vab-layout-header {
box-shadow: $base-box-shadow;
}
}
&.fixed {
padding-top: $base-nav-height + $base-tabs-height;
}
&.fixed.no-tabs-bar {
padding-top: $base-nav-height;
}
}
:deep() {
.fixed-header {
position: fixed;
top: 0;
right: 0;
z-index: $base-z-index - 1;
width: 100%;
}
.vab-main {
position: relative;
width: auto;
min-height: 100%;
margin-left: var(--el-left-menu-width);
&.is-collapse-main {
margin-left: $base-left-menu-width-min;
.fixed-header {
width: $base-right-content-width-min;
}
}
&:not(.is-collapse-main) {
.fixed-header {
width: calc(100% - var(--el-left-menu-width));
}
}
}
}
/* 手机端开始 */
&.mobile {
:deep() {
.vab-layout-vertical {
.el-scrollbar.vab-side-bar.is-collapse {
width: 0;
}
.vab-main {
.fixed-header {
width: 100%;
}
margin-left: 0;
}
}
/* 隐藏分页和页码跳转 */
.el-pager,
.el-pagination__jump {
display: none;
}
}
}
/* 手机端结束 */
}
</style>