搜索结果列表页面开发
This commit is contained in:
199
src/layouts/v2/DefaultLayout/index.vue
Normal file
199
src/layouts/v2/DefaultLayout/index.vue
Normal file
@@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<d-layout class="d-layout h-full">
|
||||
<d-header class="d-header">
|
||||
<!-- header -->
|
||||
<Header @clickMenu="handleClickMenu" :asideSetShow="asideSetShow" ref="refHeader">
|
||||
<!-- 二级导航左侧内容 -->
|
||||
<template v-if="$slots.headerLeft && !route?.meta?.hideNav" #info>
|
||||
<slot name="headerLeft"></slot>
|
||||
</template>
|
||||
|
||||
<!-- 二级导航右侧内容 -->
|
||||
<template v-if="$slots.headerRight && !route?.meta?.hideNav" #menu>
|
||||
<slot name="headerRight"></slot>
|
||||
</template>
|
||||
|
||||
<template v-if="$slots.bodyHeader && !route?.meta?.hideNav" #bodyHeader>
|
||||
<slot name="bodyHeader"></slot>
|
||||
</template>
|
||||
<template v-if="$slots.headerBottom && !route?.meta?.hideNav" #headerBottom>
|
||||
<slot name="headerBottom"></slot>
|
||||
</template>
|
||||
</Header>
|
||||
</d-header>
|
||||
<!-- 顶栏信息 -->
|
||||
<div v-if="$slots.contentBanner">
|
||||
<slot name="contentBanner"></slot>
|
||||
</div>
|
||||
<!-- 主体 -->
|
||||
<d-layout class="flex-col">
|
||||
<d-aside class="left-side-bar" v-if="asideSetShow" :style="{ width: mainMarginLeftWidth + 'px' }">
|
||||
<Aside :asideDefaultWidth="mainMarginLeftWidth"></Aside>
|
||||
</d-aside>
|
||||
<d-drawer v-model="asideVisible" position="left" lock-scroll style="max-height: 100%; top: 0;"
|
||||
:style="{ width: '240px', overflowY: 'hidden' }">
|
||||
<div class="p-[16px] flex justify-between items-center h-[60px]">
|
||||
<GLink class="g-toolbar-left-logo" href="/" />
|
||||
<d-icon class="cursor-pointer" name="close" @click="asideVisible = false"></d-icon>
|
||||
</div>
|
||||
<Aside :asideDefaultWidth="240" @on-select="handleClickMenu" style="height: calc(100% - 60px);padding-top: 0px;"></Aside>
|
||||
</d-drawer>
|
||||
<d-layout :style="{ marginLeft: mainMarginLeftWidth + 'px', transition: 'margin-left ease 0.1s' }">
|
||||
<d-layout :class="responsiveClass" :style="{ minHeight: `calc(100% - ${footerSize?.height.value || 0}px)` }">
|
||||
<!-- sidebar -->
|
||||
<d-aside class="d-aside pr-[32px] pt-32 g-side-border" v-if="route?.meta?.sidebarType">
|
||||
<slot name="sidebar"></slot>
|
||||
</d-aside>
|
||||
<!-- 内容 -->
|
||||
<d-content class="pl-[32px]">
|
||||
<slot name="content">
|
||||
<RouterView />
|
||||
</slot>
|
||||
</d-content>
|
||||
</d-layout>
|
||||
<!-- footer -->
|
||||
<!-- <d-footer v-if="!route?.meta?.hiddenFooter" ref="refFooter">
|
||||
<slot name="footer">
|
||||
<Footer />
|
||||
</slot>
|
||||
</d-footer> -->
|
||||
</d-layout>
|
||||
</d-layout>
|
||||
|
||||
<!-- 浮动工具栏(移动端不显示) -->
|
||||
<ToolsFloat v-if="showToolsFloat" />
|
||||
|
||||
</d-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineOptions({ name: 'DefaultLayout' });
|
||||
import { RouterView, useRoute, useRouter } from 'vue-router';
|
||||
import { computed, ref, watch, watchEffect, onMounted, onUnmounted } from 'vue';
|
||||
import Header from '@/components/Header/index.vue';
|
||||
import Footer from '@/components/Footer/index.vue';
|
||||
import Aside from './aside.vue';
|
||||
import { useGlobalInfoStore } from '@/stores/Global';
|
||||
|
||||
import ToolsFloat from '@/components/ToolsFloat/index.vue';
|
||||
import { useStorage, useElementSize } from '@vueuse/core';
|
||||
import { usePageResize } from '@/utils/hooks/usePageResize';
|
||||
import microApp from '@micro-zoe/micro-app';
|
||||
defineProps<{ customAside?: boolean; }>();
|
||||
const router = useRouter();
|
||||
const solt = defineSlots();
|
||||
const sizeStore = usePageResize();
|
||||
const globalStore = useGlobalInfoStore();
|
||||
const route = useRoute();
|
||||
const asideVisible = ref(false);
|
||||
const refFooter = ref(null);
|
||||
const refHeader: any = ref(null);
|
||||
const footerSize = useElementSize(refFooter);
|
||||
|
||||
// aside 设置可见性 header有两层,有顶栏信息,两层sidebar 都不可见
|
||||
const asideSetShow = computed(() => {
|
||||
if (route.meta.asideMenu === 'drawer') return false;
|
||||
return refHeader.value?.height <= 56 && !solt.contentBanner && !route.meta.sidebarType;
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
clickMenu: [];
|
||||
}>();
|
||||
watch(route, () => {
|
||||
globalStore.setIsNotFound(false); // 切换路由默认不显示404,防止一直显示404
|
||||
}, { deep: true });
|
||||
|
||||
const asideDefaultWidth = useStorage('asideDefaultWidth', sizeStore.isMobile.value ? 0 : 240);
|
||||
const mainMarginLeftWidth = computed(() => {
|
||||
if (!asideSetShow.value || sizeStore.isMobile.value) {
|
||||
return 0;
|
||||
} else {
|
||||
return asideDefaultWidth.value;
|
||||
}
|
||||
});
|
||||
|
||||
// 是否展示浮动工具栏(非移动端 || 未设置隐藏)
|
||||
const showToolsFloat = computed(() => {
|
||||
return sizeStore.widthType.value !== 'sm' && !route.meta.hiddenToolsFloat;
|
||||
});
|
||||
|
||||
const responsiveClass = computed(() => { // 控制移动和pc布局
|
||||
let className = 'm-auto max-w-normal px-normal w-full';
|
||||
let viewportContent = 'width=device-width,initial-scale=0,user-scalable=yes,maximum-scale=1.0';
|
||||
|
||||
if (sizeStore.isMobile.value) { // 设备是否为手机
|
||||
if (route?.meta?.hasMobile) { // 是否有手机端页面
|
||||
className = 'w-full';
|
||||
viewportContent = 'width=device-width, initial-scale=1.0';
|
||||
}
|
||||
} else {
|
||||
if (route?.meta?.className) {
|
||||
className = `${route?.meta?.className as string}`;
|
||||
}
|
||||
if (route.name === 'homepage' && globalStore.namespaceType === 1) { // 组织主页样式特殊处理
|
||||
className = 'm-auto min-w-sm px-normal max-w-[1280px] w-full pt-[12px]';
|
||||
}
|
||||
}
|
||||
document?.querySelector("meta[name='viewport']")?.setAttribute('content', viewportContent);
|
||||
return className;
|
||||
});
|
||||
|
||||
const handleClickMenu = () => {
|
||||
if (sizeStore.isMobile.value || !asideSetShow.value) { // 不可见时弹框
|
||||
asideVisible.value = !asideVisible.value;
|
||||
} else { // 可见时收起
|
||||
asideDefaultWidth.value = asideDefaultWidth.value >= 240 ? 0 : 240;
|
||||
}
|
||||
};
|
||||
|
||||
const outOfSearch = ref(true); // 在search页面隐藏footer
|
||||
router.afterEach((to, form) => {
|
||||
outOfSearch.value = to.name !== 'search';
|
||||
});
|
||||
microApp.router.afterEach({
|
||||
'micoro-app-homeweb-app': (to, from) => {
|
||||
outOfSearch.value = to.pathname !== '/search';
|
||||
}
|
||||
});
|
||||
const checkPage = (data: any) => {
|
||||
if (data.type === 'checkPage') {
|
||||
return 'ready';
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
microApp.addDataListener('micoro-app-homeweb-app', checkPage, false);
|
||||
});
|
||||
onUnmounted(() => {
|
||||
microApp.removeDataListener('micoro-app-homeweb-app', checkPage);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.left-side-bar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
top: 56px;
|
||||
background-color: #fff;
|
||||
z-index: 10;
|
||||
border-right: 1px solid #F1F1F8;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
transition: width ease 0.1s;
|
||||
}
|
||||
|
||||
.g-toolbar-left-logo {
|
||||
display: inline-block;
|
||||
width: 102px;
|
||||
height: 28px;
|
||||
background: url(../../assets/imgs/logo/logo.png) no-repeat;
|
||||
background-size: contain;
|
||||
vertical-align: middle;
|
||||
background-position: 0 center;
|
||||
}
|
||||
|
||||
.g-side-border {
|
||||
border-right: 1px solid var(--devui-dividing-line);
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user