基于vue3.0和element-plus的组件库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

233 lines
5.3 KiB

<template>
<el-container :style="appMain" ref="main" v-show="!flag.loading">
<el-aside :width="state.size.asideWidth">
<MenuTree :title="title || t('title')" :logo="logo" :data="menus" mode="vertical" />
</el-aside>
<el-container id="container">
<el-header v-show="state.size.headHeight != '0px'" class="app-head" :height="state.size.headHeight">
<Head :title="title" :logo="logo" :username="username" :closeAble="true">
<template #left>
<MenuTree v-show="state.size.asideWidth == '0px'" :data="menus" mode="horizontal" />
</template>
<HeadPersonal @updatePwd="updatePwd" @logout="onLogout" :center="center" />
<Fullscreen />
<LangChange v-if="langAble" />
<SizeChange v-if="sizeAble" />
<slot></slot>
</Head>
</el-header>
<el-main class="app-main">
<router-view />
</el-main>
</el-container>
</el-container>
</template>
<script lang="ts" setup>
import { reactive, onMounted, ref, onBeforeUnmount } from "vue";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { NoobHead, Api, Styles, Size } from "noob-mengyxu";
const { Head, MenuTree, HeadPersonal, Fullscreen, StyleChange, LangChange, SizeChange } = NoobHead;
import md5 from "js-md5";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const emit = defineEmits(["updatePwd", "logout"]);
const router = useRouter();
const appMain = reactive({
height: window.innerHeight + "px",
backgroundColor: state.style.bodyBg,
});
const main = ref();
const flag = reactive({
showHeader: true,
showAside: true,
loading: false,
});
let interval = 0;
state.style = Styles.light;
const props = defineProps({
title: {
type: String,
default: null,
},
menus: {
type: Array<any>(),
default: null,
},
styleAble: {
type: Boolean,
default: true,
},
sizeAble: {
type: Boolean,
default: true,
},
langAble: {
type: Boolean,
default: true,
},
center: {
type: String,
default: "home",
},
checkUser: {
type: Boolean,
default: true,
},
username: {
type: String,
default: null,
},
logo: {
type: String,
default: null,
},
});
const onResize = () => {
const height = window.innerHeight;
appMain.height = height + "px";
commit("initSize", [height, window.innerWidth]);
};
const getUser = (first?) => {
if (!props.checkUser) {
return;
}
first && (flag.loading = true);
Api.pub.getInfo().then((rsp) => {
first && (flag.loading = false);
if (rsp) {
commit("updateState", ["user", rsp]);
} else {
router.push("/login");
}
});
};
const onLogout = () => {
Api.pub.logout().then((rsp) => {
getUser();
});
};
const updatePwd = (pwd) => {
pwd.old = md5(pwd.old);
pwd.new = md5(pwd.new);
pwd.reNew = md5(pwd.reNew);
emit("updatePwd", pwd);
Api.user.updatePwd(pwd);
};
onMounted(() => {
router.push("/");
dispatch("getMenus");
getUser(true);
interval = setInterval(getUser, 5000);
window.onresize = onResize;
onResize();
commit("updateState", ["style", Styles.plain]);
});
onBeforeUnmount(() => {
clearInterval(interval);
});
</script>
<style lang="scss">
body {
font-size: v-bind("state.size.fontSize") !important;
font-family: "Microsoft YaHei";
width: 100%;
height: 100%;
overflow: hidden;
padding: 0px;
margin: 0px;
}
</style>
<style lang="scss" scoped>
.app-main {
box-shadow: 2px 2px 5px 3px #e5e6eb;
border-radius: 4px;
margin: 0px 0px 0px 3px !important;
padding: 0 !important;
height: v-bind("state.size.mainHeight");
}
.el-header,
.main-head,
.main-table {
padding: 0;
}
#container,
.app-main {
background-color: v-bind("state.style.bodyBg");
color: v-bind("state.style.color");
font-size: v-bind("state.size.fontSize");
}
.app-head {
padding: 0px !important;
background-color: v-bind("state.style.headBg");
height: v-bind("state.size.headHeight");
}
.head-icon {
float: right;
cursor: pointer;
height: v-bind("state.size.headHeight") !important;
margin-right: 20px !important;
font-size: v-bind("state.size.headIconSize") !important;
align-items: center !important;
color: v-bind("state.style.color") !important;
}
.form-item {
margin-right: v-bind("state.size.searchMargin");
&.full {
width: 100%;
margin-right: 0px;
}
}
:deep(.el-input),
:deep(.el-textarea),
:deep(.el-date-editor),
:deep(.el-input__wrapper) {
--el-input-bg-color: v-bind("state.style.itemBg") !important;
--el-fill-color-blank: v-bind("state.style.itemBg") !important;
--el-input-text-color: v-bind("state.style.color") !important;
}
:deep(.el-popper) {
--el-bg-color-overlay: v-bind("state.style.itemBg") !important;
--el-fill-color-light: v-bind("state.style.bodyBg") !important;
text-align: left;
}
:deep(.el-dialog) {
--el-dialog-bg-color: v-bind("state.style.bodyBg") !important;
}
:deep(.el-drawer) {
--el-drawer-bg-color: v-bind("state.style.bodyBg") !important;
}
:deep(*) {
--el-text-color-regular: v-bind("state.style.color") !important;
--el-text-color-primary: v-bind("state.style.color") !important;
--el-disabled-bg-color: v-bind("state.style.itemBg") !important;
}
:deep(*::selection) {
background-color: v-bind("state.style.selectionBg");
color: v-bind("state.style.selectionColor");
}
</style>