This commit is contained in:
zzc
2025-03-28 18:28:06 +08:00
commit 939c43f281
206 changed files with 30419 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
<template>
<router-view />
</template>

View File

@@ -0,0 +1,46 @@
<template>
<div class="vab-ad">
<el-carousel v-if="adList" :autoplay="true" :interval="3000" direction="vertical" height="30px" indicator-position="none">
<el-carousel-item v-for="(item, index) in adList" :key="index">
<el-tag type="warning">Ad</el-tag>
<a :href="item.url" target="_blank">{{ item.title }}</a>
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
import { getList } from '@/api/ad'
export default {
name: 'VabAd',
data() {
return {
nodeEnv: process.env.NODE_ENV,
adList: [],
}
},
created() {
this.fetchData()
},
methods: {
async fetchData() {
const { data } = await getList()
this.adList = data
},
},
}
</script>
<style lang="scss" scoped>
.vab-ad {
height: 30px;
padding-right: $base-padding;
padding-left: $base-padding;
margin-bottom: -20px;
line-height: 30px;
cursor: pointer;
a {
color: #999;
}
}
</style>

View File

@@ -0,0 +1,107 @@
<template>
<div v-if="routerView" class="app-main-container">
<!-- <vab-github-corner /> -->
<transition mode="out-in" name="fade-transform">
<keep-alive :include="cachedRoutes" :max="keepAliveMaxNum">
<router-view :key="key" class="app-main-height" />
</keep-alive>
</transition>
<footer v-show="footerCopyright" class="footer-copyright">
Copyright
<vab-icon :icon="['fas', 'copyright']"></vab-icon>
{{ titleName }} {{ fullYear }}
</footer>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
import { copyright, footerCopyright, keepAliveMaxNum, title } from '@/config'
export default {
name: 'VabAppMain',
data() {
return {
show: false,
fullYear: new Date().getFullYear(),
copyright,
title,
keepAliveMaxNum,
routerView: true,
footerCopyright,
}
},
computed: {
...mapGetters({
visitedRoutes: 'tabsBar/visitedRoutes',
device: 'settings/device',
titleName: 'settings/title',
}),
cachedRoutes() {
const cachedRoutesArr = []
this.visitedRoutes.forEach((item) => {
if (!item.meta.noKeepAlive) {
cachedRoutesArr.push(item.name)
}
})
return cachedRoutesArr
},
key() {
return this.$route.path
},
},
watch: {
$route: {
handler(route) {
if ('mobile' === this.device) this.foldSideBar()
},
immediate: true,
},
},
created() {
const handleReloadRouterView = () => {
this.routerView = false
this.$nextTick(() => {
this.routerView = true
})
};
//重载所有路由
this.$baseEventBus.$on('reload-router-view', handleReloadRouterView)
this.$once('hook:beforeDestroy', () => {
this.$baseEventBus.$off('reload-router-view', handleReloadRouterView);
});
},
mounted() {},
methods: {
...mapActions({
foldSideBar: 'settings/foldSideBar',
}),
},
}
</script>
<style lang="scss" scoped>
.app-main-container {
position: relative;
width: 100%;
overflow: hidden;
.vab-keel {
margin: $base-padding;
}
.app-main-height {
min-height: $base-app-main-height;
}
.footer-copyright {
min-height: 55px;
line-height: 55px;
color: rgba(0, 0, 0, 0.45);
text-align: center;
border-top: 1px dashed $base-border-color;
}
}
</style>

View File

@@ -0,0 +1,100 @@
<template>
<el-dropdown @command="handleCommand">
<span class="avatar-dropdown">
<!--<el-avatar class="user-avatar" :src="avatar"></el-avatar>-->
<img :src="avatar" alt="" class="user-avatar" />
<div class="user-name">
{{ username }}
<i class="el-icon-arrow-down el-icon--right"></i>
</div>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="github">github地址</el-dropdown-item>
<el-dropdown-item command="gitee" divided>码云地址</el-dropdown-item>
<el-dropdown-item command="pro" divided>pro付费版地址</el-dropdown-item>
<el-dropdown-item command="plus" divided>plus付费版地址</el-dropdown-item>
<el-dropdown-item command="shop" divided>shop-vite付费版地址</el-dropdown-item>
<el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
import { mapGetters } from 'vuex'
import { recordRoute } from '@/config'
export default {
name: 'VabAvatar',
computed: {
...mapGetters({
avatar: 'user/avatar',
username: 'user/username',
}),
},
methods: {
handleCommand(command) {
switch (command) {
case 'logout':
this.logout()
break
case 'personalCenter':
this.personalCenter()
break
case 'github':
window.open('https://github.com/zxwk1998/vue-admin-better')
break
case 'gitee':
window.open('https://gitee.com/chu1204505056/vue-admin-better')
break
case 'pro':
window.open('https://vuejs-core.cn/admin-pro/')
break
case 'plus':
window.open('https://vuejs-core.cn/admin-plus/')
case 'shop':
window.open('https://vuejs-core.cn/shop-vite/')
}
},
personalCenter() {
this.$router.push('/personalCenter/personalCenter')
},
logout() {
this.$baseConfirm('您确定要退出' + this.$baseTitle + '吗?', null, async () => {
await this.$store.dispatch('user/logout')
if (recordRoute) {
const fullPath = this.$route.fullPath
this.$router.push(`/login?redirect=${fullPath}`)
} else {
this.$router.push('/login')
}
})
},
},
}
</script>
<style lang="scss" scoped>
.avatar-dropdown {
display: flex;
align-content: center;
align-items: center;
justify-content: center;
justify-items: center;
height: 50px;
padding: 0;
.user-avatar {
width: 40px;
height: 40px;
cursor: pointer;
border-radius: 50%;
}
.user-name {
position: relative;
margin-left: 5px;
margin-left: 5px;
cursor: pointer;
}
}
</style>

View File

@@ -0,0 +1,61 @@
<template>
<el-breadcrumb class="breadcrumb-container" separator=">">
<el-breadcrumb-item v-for="item in list" :key="item.path">
{{ item.meta.title }}
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
export default {
name: 'VabBreadcrumb',
data() {
return {
list: this.getBreadcrumb(),
}
},
watch: {
$route() {
this.list = this.getBreadcrumb()
},
},
methods: {
getBreadcrumb() {
return this.$route.matched.filter((item) => item.name && item.meta.title)
},
},
}
</script>
<style lang="scss" scoped>
.breadcrumb-container {
height: $base-nav-bar-height;
font-size: $base-font-size-default;
line-height: $base-nav-bar-height;
::v-deep {
.el-breadcrumb__item {
.el-breadcrumb__inner {
a {
display: flex;
float: left;
font-weight: normal;
color: #515a6e;
i {
margin-right: 3px;
}
}
}
&:last-child {
.el-breadcrumb__inner {
a {
color: #999;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,85 @@
<template>
<div :class="'logo-container-' + layout">
<router-link to="/">
<!-- 这里是logo变更的位置 -->
<vab-remix-icon v-if="logo" :icon-class="logo" class="logo" />
<span :class="{ 'hidden-xs-only': layout === 'horizontal' }" :title="title" class="title">
{{ title }}
</span>
</router-link>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'VabLogo',
computed: {
...mapGetters({
logo: 'settings/logo',
layout: 'settings/layout',
title: 'settings/title',
}),
},
}
</script>
<style lang="scss" scoped>
@mixin container {
position: relative;
height: $base-top-bar-height;
overflow: hidden;
line-height: $base-top-bar-height;
background: $base-menu-background;
}
@mixin logo {
display: inline-block;
width: 34px;
height: 34px;
margin-right: 3px;
color: $base-title-color;
vertical-align: middle;
}
@mixin title {
display: inline-block;
overflow: hidden;
font-size: 24px;
line-height: 55px;
color: $base-title-color;
text-overflow: ellipsis;
white-space: nowrap;
vertical-align: middle;
margin-left: 10px;
}
.logo-container-horizontal {
@include container;
.logo {
@include logo;
}
.title {
@include title;
}
}
.logo-container-vertical {
@include container;
height: $base-logo-height;
line-height: $base-logo-height;
text-align: center;
.logo {
@include logo;
}
.title {
@include title;
max-width: calc(#{$base-left-menu-width} - 60px);
}
}
</style>

View File

@@ -0,0 +1,136 @@
<template>
<div class="nav-bar-container">
<el-row :gutter="15">
<el-col :lg="12" :md="12" :sm="12" :xl="12" :xs="4">
<div class="left-panel">
<i
:class="collapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'"
:title="collapse ? '展开' : '收起'"
class="fold-unfold"
@click="handleCollapse"
></i>
<vab-breadcrumb class="hidden-xs-only" />
</div>
</el-col>
<el-col :lg="12" :md="12" :sm="12" :xl="12" :xs="20">
<div class="right-panel">
<vab-error-log />
<vab-full-screen-bar @refresh="refreshRoute" />
<vab-theme-bar class="hidden-xs-only" />
<vab-icon :icon="['fas', 'redo']" :pulse="pulse" title="重载所有路由" @click="refreshRoute" />
<vab-avatar />
<!-- <vab-icon
title="退出系统"
:icon="['fas', 'sign-out-alt']"
@click="logout"
/>-->
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
export default {
name: 'VabNavBar',
data() {
return {
pulse: false,
timeOutID: null
}
},
computed: {
...mapGetters({
collapse: 'settings/collapse',
visitedRoutes: 'tabsBar/visitedRoutes',
device: 'settings/device',
routes: 'routes/routes',
}),
},
methods: {
...mapActions({
changeCollapse: 'settings/changeCollapse',
}),
handleCollapse() {
this.changeCollapse()
},
async refreshRoute() {
this.$baseEventBus.$emit('reload-router-view')
this.pulse = true
this.timeOutID = setTimeout(() => {
this.pulse = false
}, 1000)
},
},
beforeDestroy() {
clearTimeout(this.timeOutID);
}
};
</script>
<style lang="scss" scoped>
.nav-bar-container {
position: relative;
height: $base-nav-bar-height;
padding-right: $base-padding;
padding-left: $base-padding;
overflow: hidden;
user-select: none;
background: $base-color-white;
box-shadow: $base-box-shadow;
.left-panel {
display: flex;
align-items: center;
justify-items: center;
height: $base-nav-bar-height;
.fold-unfold {
color: $base-color-gray;
cursor: pointer;
}
::v-deep {
.breadcrumb-container {
margin-left: 10px;
}
}
}
.right-panel {
display: flex;
align-content: center;
align-items: center;
justify-content: flex-end;
height: $base-nav-bar-height;
::v-deep {
svg {
width: 1em;
height: 1em;
margin-right: 15px;
font-size: $base-font-size-small;
color: $base-color-gray;
cursor: pointer;
fill: $base-color-gray;
}
button {
svg {
margin-right: 0;
color: $base-color-white;
cursor: pointer;
fill: $base-color-white;
}
}
.el-badge {
margin-right: 15px;
}
}
}
}
</style>

View File

@@ -0,0 +1,259 @@
<template>
<span v-if="themeBar">
<vab-icon :icon="['fas', 'palette']" title="主题配置" @click="handleOpenThemeBar" />
<div class="theme-bar-setting">
<div @click="handleOpenThemeBar">
<vab-icon :icon="['fas', 'palette']" />
<p>主题配置</p>
</div>
<div @click="handleGetCode">
<vab-icon :icon="['fas', 'laptop-code']"></vab-icon>
<p>拷贝源码</p>
</div>
</div>
<el-drawer :visible.sync="drawerVisible" append-to-body direction="rtl" size="300px" title="主题配置">
<el-scrollbar style="height: 80vh; overflow: hidden">
<div class="el-drawer__body">
<el-form ref="form" :model="theme" label-position="top">
<el-form-item label="主题">
<el-radio-group v-model="theme.name">
<el-radio-button label="default">默认</el-radio-button>
<el-radio-button label="green">绿荫草场</el-radio-button>
<el-radio-button label="glory">荣耀典藏</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="布局">
<el-radio-group v-model="theme.layout">
<el-radio-button label="vertical">纵向布局</el-radio-button>
<el-radio-button label="horizontal">横向布局</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="头部">
<el-radio-group v-model="theme.header">
<el-radio-button label="fixed">固定头部</el-radio-button>
<el-radio-button label="noFixed">不固定头部</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="多标签">
<el-radio-group v-model="theme.tabsBar">
<el-radio-button label="true">开启</el-radio-button>
<el-radio-button label="false">不开启</el-radio-button>
</el-radio-group>
</el-form-item>
</el-form>
</div>
</el-scrollbar>
<div class="el-drawer__footer">
<el-button type="primary" @click="handleSaveTheme">保存</el-button>
<el-button type="" @click="drawerVisible = false">取消</el-button>
</div>
</el-drawer>
</span>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
import { layout as defaultLayout } from '@/config'
export default {
name: 'VabThemeBar',
data() {
return {
drawerVisible: false,
theme: {
name: 'default',
layout: '',
header: 'fixed',
tabsBar: '',
},
}
},
computed: {
...mapGetters({
layout: 'settings/layout',
header: 'settings/header',
tabsBar: 'settings/tabsBar',
themeBar: 'settings/themeBar',
}),
},
created() {
const handleTheme = () => {
this.handleOpenThemeBar()
}
this.$baseEventBus.$on('theme', handleTheme)
const theme = localStorage.getItem('vue-admin-better-theme')
if (null !== theme) {
this.theme = JSON.parse(theme)
this.handleSetTheme()
} else {
this.theme.layout = this.layout
this.theme.header = this.header
this.theme.tabsBar = this.tabsBar
}
this.$once('hook:beforeDestroy', () => {
this.$baseEventBus.$off('theme', handleTheme)
})
},
methods: {
...mapActions({
changeLayout: 'settings/changeLayout',
changeHeader: 'settings/changeHeader',
changeTabsBar: 'settings/changeTabsBar',
}),
handleIsMobile() {
return document.body.getBoundingClientRect().width - 1 < 992
},
handleOpenThemeBar() {
this.drawerVisible = true
},
handleSetTheme() {
let { name, layout, header, tabsBar } = this.theme
localStorage.setItem(
'vue-admin-better-theme',
`{
"name":"${name}",
"layout":"${layout}",
"header":"${header}",
"tabsBar":"${tabsBar}"
}`
)
if (!this.handleIsMobile()) this.changeLayout(layout)
this.changeHeader(header)
this.changeTabsBar(tabsBar)
document.getElementsByTagName('body')[0].className = `vue-admin-better-theme-${name}`
this.drawerVisible = false
},
handleSaveTheme() {
this.handleSetTheme()
},
handleSetDfaultTheme() {
let { name } = this.theme
document.getElementsByTagName('body')[0].classList.remove(`vue-admin-better-theme-${name}`)
localStorage.removeItem('vue-admin-better-theme')
this.$refs['form'].resetFields()
Object.assign(this.$data, this.$options.data())
this.changeHeader(defaultLayout)
this.theme.name = 'default'
this.theme.layout = this.layout
this.theme.header = this.header
this.theme.tabsBar = this.tabsBar
this.drawerVisible = false
location.reload()
},
handleGetCode() {
const url = 'https://github.com/zxwk1998/vue-admin-better/tree/master/src/views'
let path = this.$route.path + '/index.vue'
if (path === '/vab/menu1/menu1-1/menu1-1-1/index.vue') {
path = '/vab/nested/menu1/menu1-1/menu1-1-1/index.vue'
}
if (path === '/vab/icon/awesomeIcon/index.vue') {
path = '/vab/icon/index.vue'
}
if (path === '/vab/icon/remixIcon/index.vue') {
path = '/vab/icon/remixIcon.vue'
}
if (path === '/vab/icon/colorfulIcon/index.vue') {
path = '/vab/icon/colorfulIcon.vue'
}
if (path === '/vab/table/comprehensiveTable/index.vue') {
path = '/vab/table/index.vue'
}
if (path === '/vab/table/inlineEditTable/index.vue') {
path = '/vab/table/inlineEditTable.vue'
}
window.open(url + path)
},
},
}
</script>
<style lang="scss" scoped>
@mixin right-bar {
position: fixed;
right: 0;
z-index: $base-z-index;
width: 60px;
min-height: 60px;
text-align: center;
cursor: pointer;
background: $base-color-blue;
border-radius: $base-border-radius;
> div {
padding-top: 10px;
border-bottom: 0 !important;
&:hover {
opacity: 0.9;
}
& + div {
border-top: 1px solid $base-color-white;
}
p {
padding: 0;
margin: 0;
font-size: $base-font-size-small;
line-height: 30px;
color: $base-color-white;
}
}
}
.theme-bar-setting {
@include right-bar;
top: calc((100vh - 110px) / 2);
::v-deep {
svg:not(:root).svg-inline--fa {
display: block;
margin-right: auto;
margin-left: auto;
color: $base-color-white;
}
.svg-icon {
display: block;
margin-right: auto;
margin-left: auto;
font-size: 20px;
color: $base-color-white;
fill: $base-color-white;
}
}
}
.el-drawer__body {
padding: 20px;
}
.el-drawer__footer {
border-top: 1px solid #dedede;
position: fixed;
bottom: 0;
width: 100%;
padding: 10px 0 0 20px;
height: 50px;
}
</style>
<style lang="scss">
.el-drawer__wrapper {
outline: none !important;
* {
outline: none !important;
}
}
.vab-color-picker {
.el-color-dropdown__link-btn {
display: none;
}
}
</style>

25
src/layouts/export.js Normal file
View File

@@ -0,0 +1,25 @@
/**
* @author https://github.com/zxwk1998/vue-admin-better 不想保留author可删除
* @description 公共布局及样式自动引入
*/
import Vue from 'vue'
const requireComponents = require.context('./components', true, /\.vue$/)
requireComponents.keys().forEach((fileName) => {
const componentConfig = requireComponents(fileName)
const componentName = componentConfig.default.name
Vue.component(componentName, componentConfig.default || componentConfig)
})
const requireZxLayouts = require.context('layouts', true, /\.vue$/)
requireZxLayouts.keys().forEach((fileName) => {
const componentConfig = requireZxLayouts(fileName)
const componentName = componentConfig.default.name
Vue.component(componentName, componentConfig.default || componentConfig)
})
const requireThemes = require.context('@/styles/themes', true, /\.scss$/)
requireThemes.keys().forEach((fileName) => {
require(`@/styles/themes/${fileName.slice(2)}`)
})

298
src/layouts/index.vue Normal file
View File

@@ -0,0 +1,298 @@
<template>
<div :class="classObj" class="vue-admin-better-wrapper">
<div
v-if="'horizontal' === layout"
:class="{
fixed: header === 'fixed',
'no-tabs-bar': tabsBar === 'false' || tabsBar === false,
}"
class="layout-container-horizontal"
>
<div :class="header === 'fixed' ? 'fixed-header' : ''">
<vab-top-bar />
<div v-if="tabsBar === 'true' || tabsBar === true" :class="{ 'tag-view-show': tabsBar }">
<div class="vab-main">
<vab-tabs-bar />
</div>
</div>
</div>
<div class="vab-main main-padding">
<!-- <vab-ad /> -->
<vab-app-main />
</div>
</div>
<div
v-else
:class="{
fixed: header === 'fixed',
'no-tabs-bar': tabsBar === 'false' || tabsBar === false,
}"
class="layout-container-vertical"
>
<div v-if="device === 'mobile' && collapse === false" class="mask" @click="handleFoldSideBar" />
<vab-side-bar />
<div :class="collapse ? 'is-collapse-main' : ''" class="vab-main">
<div :class="header === 'fixed' ? 'fixed-header' : ''">
<vab-nav-bar />
<vab-tabs-bar v-if="tabsBar === 'true' || tabsBar === true" />
</div>
<!-- <vab-ad /> -->
<vab-app-main />
</div>
</div>
<el-backtop />
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
import { tokenName } from '@/config'
export default {
name: 'Layout',
data() {
return {
oldLayout: '',
controller: new window.AbortController(),
timeOutID: null,
}
},
computed: {
...mapGetters({
layout: 'settings/layout',
tabsBar: 'settings/tabsBar',
collapse: 'settings/collapse',
header: 'settings/header',
device: 'settings/device',
}),
classObj() {
return {
mobile: this.device === 'mobile',
}
},
},
beforeMount() {
window.addEventListener('resize', this.handleResize)
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize)
this.controller.abort()
clearTimeout(this.timeOutID)
},
mounted() {
this.oldLayout = this.layout
const userAgent = navigator.userAgent
const isMobile = this.handleIsMobile()
if (isMobile) {
if (isMobile) {
//横向布局时如果是手机端访问那么改成纵向版
this.$store.dispatch('settings/changeLayout', 'vertical')
} else {
this.$store.dispatch('settings/changeLayout', this.oldLayout)
}
this.$store.dispatch('settings/toggleDevice', 'mobile')
this.timeOutID = setTimeout(() => {
this.$store.dispatch('settings/foldSideBar')
}, 2000)
} else {
this.$store.dispatch('settings/openSideBar')
}
this.$nextTick(() => {
window.addEventListener(
'storage',
(e) => {
if (e.key === tokenName || e.key === null) window.location.reload()
if (e.key === tokenName && e.value === null) window.location.reload()
},
{
capture: false,
signal: this.controller?.signal,
}
)
})
},
methods: {
...mapActions({
handleFoldSideBar: 'settings/foldSideBar',
}),
handleIsMobile() {
return document.body.getBoundingClientRect().width - 1 < 992
},
handleResize() {
if (!document.hidden) {
const isMobile = this.handleIsMobile()
if (isMobile) {
//横向布局时如果是手机端访问那么改成纵向版
this.$store.dispatch('settings/changeLayout', 'vertical')
} else {
this.$store.dispatch('settings/changeLayout', this.oldLayout)
}
this.$store.dispatch('settings/toggleDevice', isMobile ? 'mobile' : 'desktop')
}
},
},
}
</script>
<style lang="scss" scoped>
@mixin fix-header {
position: fixed;
top: 0;
right: 0;
left: 0;
z-index: $base-z-index - 2;
width: 100%;
overflow: hidden;
}
.vue-admin-better-wrapper {
position: relative;
width: 100%;
height: 100%;
.layout-container-horizontal {
position: relative;
&.fixed {
padding-top: calc(#{$base-top-bar-height} + #{$base-tabs-bar-height});
}
&.fixed.no-tabs-bar {
padding-top: $base-top-bar-height;
}
::v-deep {
.vab-main {
width: 88%;
margin: auto;
}
.fixed-header {
@include fix-header;
}
.tag-view-show {
background: $base-color-white;
box-shadow: $base-box-shadow;
}
.nav-bar-container {
.fold-unfold {
display: none;
}
}
.main-padding {
.app-main-container {
margin-top: $base-padding;
margin-bottom: $base-padding;
background: $base-color-white;
}
}
}
}
.layout-container-vertical {
position: relative;
.mask {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: $base-z-index - 1;
width: 100%;
height: 100vh;
overflow: hidden;
background: #000;
opacity: 0.5;
}
&.fixed {
padding-top: calc(#{$base-nav-bar-height} + #{$base-tabs-bar-height});
}
&.fixed.no-tabs-bar {
padding-top: $base-nav-bar-height;
}
.vab-main {
position: relative;
min-height: 100%;
margin-left: $base-left-menu-width;
background: #f6f8f9;
transition: $base-transition;
::v-deep {
.fixed-header {
@include fix-header;
left: $base-left-menu-width;
width: $base-right-content-width;
box-shadow: $base-box-shadow;
transition: $base-transition;
}
.nav-bar-container {
position: relative;
box-sizing: border-box;
}
.tabs-bar-container {
box-sizing: border-box;
}
.app-main-container {
width: calc(100% - #{$base-padding} - #{$base-padding});
margin: $base-padding auto;
background: $base-color-white;
border-radius: $base-border-radius;
}
}
&.is-collapse-main {
margin-left: $base-left-menu-width-min;
::v-deep {
.fixed-header {
left: $base-left-menu-width-min;
width: calc(100% - 65px);
}
}
}
}
}
/* 手机端开始 */
&.mobile {
::v-deep {
.el-pager,
.el-pagination__jump {
display: none;
}
.layout-container-vertical {
.el-scrollbar.side-bar-container.is-collapse {
width: 0;
}
.vab-main {
width: 100%;
margin-left: 0;
}
}
.vab-main {
.fixed-header {
left: 0 !important;
width: 100% !important;
}
}
}
}
/* 手机端结束 */
}
</style>