fix: 修复取消固定头部问题 (#75)

* fix: 修复取消固定头部问题

* perf: simplify the layout code
This commit is contained in:
啝裳 2021-10-27 14:40:31 +08:00 committed by GitHub
parent 5a78685ac9
commit 1fa5793ec4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 166 additions and 70 deletions

View File

@ -45,5 +45,6 @@
"source.fixAll.eslint": true "source.fixAll.eslint": true
}, },
"volar.tsPlugin": true, "volar.tsPlugin": true,
"typescript.tsdk": "node_modules/typescript/lib" "typescript.tsdk": "node_modules/typescript/lib",
"i18n-ally.localesPaths": ["src/plugins/i18n"]
} }

View File

@ -1,42 +1,72 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, getCurrentInstance } from "vue"; import {
h,
ref,
computed,
Transition,
defineComponent,
getCurrentInstance
} from "vue";
import { RouterView } from "vue-router";
import { usePermissionStoreHook } from "/@/store/modules/permission"; import { usePermissionStoreHook } from "/@/store/modules/permission";
const props = defineProps({
fixedHeader: Boolean
});
const keepAlive: Boolean = ref( const keepAlive: Boolean = ref(
getCurrentInstance().appContext.config.globalProperties.$config?.KeepAlive getCurrentInstance().appContext.config.globalProperties.$config?.KeepAlive
); );
const transition = computed(() => { const transitions = computed(() => {
return route => { return route => {
return route.meta.transition; return route.meta.transition;
}; };
}); });
const transitionMain = defineComponent({
render() {
return h(
Transition,
{
name:
transitions.value(this.route) &&
this.route.meta.transition.enterTransition
? "pure-classes-transition"
: (transitions.value(this.route) &&
this.route.meta.transition.name) ||
"fade-transform",
enterActiveClass:
transitions.value(this.route) &&
`animate__animated ${this.route.meta.transition.enterTransition}`,
leaveActiveClass:
transitions.value(this.route) &&
`animate__animated ${this.route.meta.transition.leaveTransition}`,
mode: "out-in",
appear: true
},
{
default: () => [this.$slots.default()]
}
);
},
props: {
route: {
type: undefined,
required: true
}
}
});
</script> </script>
<template> <template>
<section class="app-main"> <section
<el-scrollbar> :class="[props.fixedHeader ? 'app-main' : 'app-main-nofixed-header']"
<el-backtop target=".app-main .el-scrollbar__wrap"></el-backtop> >
<router-view> <router-view>
<template #default="{ Component, route }"> <template #default="{ Component, route }">
<transition <el-scrollbar v-if="props.fixedHeader">
:name=" <el-backtop target=".app-main .el-scrollbar__wrap"></el-backtop>
transition(route) && route.meta.transition.enterTransition <transitionMain :route="route">
? 'pure-classes-transition'
: (transition(route) && route.meta.transition.name) ||
'fade-transform'
"
:enter-active-class="
transition(route) &&
`animate__animated ${route.meta.transition.enterTransition}`
"
:leave-active-class="
transition(route) &&
`animate__animated ${route.meta.transition.leaveTransition}`
"
mode="out-in"
appear
>
<keep-alive <keep-alive
v-if="keepAlive" v-if="keepAlive"
:include="usePermissionStoreHook().cachePageList" :include="usePermissionStoreHook().cachePageList"
@ -44,10 +74,21 @@ const transition = computed(() => {
<component :is="Component" :key="route.fullPath" /> <component :is="Component" :key="route.fullPath" />
</keep-alive> </keep-alive>
<component v-else :is="Component" :key="route.fullPath" /> <component v-else :is="Component" :key="route.fullPath" />
</transition> </transitionMain>
</template> </el-scrollbar>
</router-view> <div v-else>
</el-scrollbar> <transitionMain :route="route">
<keep-alive
v-if="keepAlive"
:include="usePermissionStoreHook().cachePageList"
>
<component :is="Component" :key="route.fullPath" />
</keep-alive>
<component v-else :is="Component" :key="route.fullPath" />
</transitionMain>
</div>
</template>
</router-view>
</section> </section>
</template> </template>
@ -58,4 +99,10 @@ const transition = computed(() => {
position: relative; position: relative;
overflow-x: hidden; overflow-x: hidden;
} }
.app-main-nofixed-header {
width: 100%;
min-height: 100vh;
position: relative;
}
</style> </style>

View File

@ -1,32 +1,6 @@
<script lang="ts">
import { routerArrays } from "./types";
export default {
computed: {
layout() {
if (!this.$storage.layout) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
this.$storage.layout = { layout: "vertical-dark" };
}
if (
!this.$storage.routesInStorage ||
this.$storage.routesInStorage.length === 0
) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
this.$storage.routesInStorage = routerArrays;
}
if (!this.$storage.locale) {
// eslint-disable-next-line
this.$storage.locale = { locale: "zh" };
useI18n().locale.value = "zh";
}
return this.$storage?.layout.layout;
}
}
};
</script>
<script setup lang="ts"> <script setup lang="ts">
import { import {
h,
ref, ref,
unref, unref,
reactive, reactive,
@ -34,10 +8,12 @@ import {
onMounted, onMounted,
watchEffect, watchEffect,
onBeforeMount, onBeforeMount,
defineComponent,
getCurrentInstance getCurrentInstance
} from "vue"; } from "vue";
import { setType } from "./types"; import { setType } from "./types";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { routerArrays } from "./types";
import { emitter } from "/@/utils/mitt"; import { emitter } from "/@/utils/mitt";
import { useEventListener } from "@vueuse/core"; import { useEventListener } from "@vueuse/core";
import { storageLocal } from "/@/utils/storage"; import { storageLocal } from "/@/utils/storage";
@ -62,6 +38,23 @@ const hiddenSideBar = ref(
getCurrentInstance().appContext.config.globalProperties.$config?.HiddenSideBar getCurrentInstance().appContext.config.globalProperties.$config?.HiddenSideBar
); );
const layout = computed(() => {
if (!instance.layout) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
instance.layout = { layout: "vertical-dark" };
}
if (!instance.routesInStorage || instance.routesInStorage.length === 0) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
instance.routesInStorage = routerArrays;
}
if (!instance.locale) {
// eslint-disable-next-line
instance.locale = { locale: "zh" };
useI18n().locale.value = "zh";
}
return instance?.layout.layout;
});
const set: setType = reactive({ const set: setType = reactive({
sidebar: computed(() => { sidebar: computed(() => {
return useAppStoreHook().sidebar; return useAppStoreHook().sidebar;
@ -141,6 +134,42 @@ onMounted(() => {
onBeforeMount(() => { onBeforeMount(() => {
useEventListener("resize", $_resizeHandler); useEventListener("resize", $_resizeHandler);
}); });
const layoutHeader = defineComponent({
render() {
return h(
"div",
{ class: { "fixed-header": set.fixedHeader } },
{
default: () => [
!hiddenSideBar.value && layout.value.includes("vertical")
? h(navbar)
: h("div"),
!hiddenSideBar.value && layout.value.includes("horizontal")
? h(Horizontal)
: h("div"),
h(
tag,
{},
{
default: () => [
h(
"span",
{ onClick: onFullScreen },
{
default: () => [
!hiddenSideBar.value ? h(fullScreen) : h(exitScreen)
]
}
)
]
}
)
]
}
);
}
});
</script> </script>
<template> <template>
@ -156,20 +185,17 @@ onBeforeMount(() => {
/> />
<Vertical v-show="!hiddenSideBar && layout.includes('vertical')" /> <Vertical v-show="!hiddenSideBar && layout.includes('vertical')" />
<div :class="['main-container', hiddenSideBar ? 'main-hidden' : '']"> <div :class="['main-container', hiddenSideBar ? 'main-hidden' : '']">
<div :class="{ 'fixed-header': set.fixedHeader }"> <div v-if="set.fixedHeader">
<!-- 顶部导航栏 --> <layout-header />
<navbar v-show="!hiddenSideBar && layout.includes('vertical')" /> <!-- 主体内容 -->
<!-- tabs标签页 --> <app-main :fixed-header="set.fixedHeader" />
<Horizontal v-show="!hiddenSideBar && layout.includes('horizontal')" />
<tag>
<span @click="onFullScreen">
<fullScreen v-if="!hiddenSideBar" />
<exitScreen v-else />
</span>
</tag>
</div> </div>
<!-- 主体内容 --> <el-scrollbar v-else>
<app-main /> <el-backtop target=".main-container .el-scrollbar__wrap"></el-backtop>
<layout-header />
<!-- 主体内容 -->
<app-main :fixed-header="set.fixedHeader" />
</el-scrollbar>
</div> </div>
<!-- 系统设置 --> <!-- 系统设置 -->
<setting /> <setting />

View File

@ -16,11 +16,33 @@
$menuText: #7a80b4; $menuText: #7a80b4;
$menuActiveText: #7a80b4; $menuActiveText: #7a80b4;
@media screen and (min-width: 150px) and (max-width: 420px) {
.app-main-nofixed-header {
overflow-y: hidden;
}
}
@media screen and (min-width: 420px) {
.app-main-nofixed-header {
overflow: hidden;
}
}
.main-container { .main-container {
height: 100vh;
min-height: 100%; min-height: 100%;
transition: margin-left 0.28s; transition: margin-left 0.28s;
margin-left: $sideBarWidth; margin-left: $sideBarWidth;
position: relative; position: relative;
@media screen and (min-width: 150px) and (max-width: 420px) {
.el-scrollbar__view {
overflow-y: hidden;
}
}
@media screen and (min-width: 420px) {
.el-scrollbar__view {
overflow: hidden;
}
}
} }
.fixed-header { .fixed-header {