123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- <template>
- <main-framework :class="`main-theme main-theme--${theme}`" :hide-footer="hideFooter" :layout="layout" :with-tabs="withTabs">
- <template #name="{isCollapse}">
- <slot name="collapse" v-if="isCollapse">
- <span style="margin-left: 8px;">{{name?.[0]}}</span>
- </slot>
- <slot name="expand" v-else>
- <span style="margin-left: 8px;">{{name}}</span>
- </slot>
- <slot name="name" :is-collapse="isCollapse"></slot>
- </template>
- <template #nav="{isCollapse}">
- <!-- 经过asideNav组件时menu会注入一个_hasChildren属性用于判断是否存在子menu需要渲染-->
- <slot name="nav">
- <cip-main-nav :nav-menu="dynamicMenu"
- :privileges="privileges"
- :mode="navMode"
- :isCollapse="isCollapse"
- :badgeMap="badgeMap"
- @triggerGetBadge="consumptionBadgeFn"/>
- </slot>
- </template>
- <template #headerNav>
- <!-- 平铺模式的菜单[注:仅显示一层]-->
- <cip-main-nav :nav-menu="menu"
- v-model:activeMenu="activeMenu"
- :privileges="privileges"
- mode="horizontal"
- :top-menu-only="true"
- :badgeMap="badgeMap"
- @triggerGetBadge="consumptionBadgeFn"/>
- </template>
- <template #tabs>
- <cip-tabs :menu="menu" ref="tabsRef" :menu-title-map="menuPathMap" :home-view="homeView" v-model:cache="cache"/>
- </template>
- <template #breadcrumb>
- <cip-main-breadcrumb />
- </template>
- <template #header>
- <header-bar>
- <template #header-user><slot name="header-user" /></template>
- <template #dropdown><slot name="dropdown" /></template>
- <template #pre-dropdown><slot name="pre-dropdown" /></template>
- </header-bar>
- </template>
- <cip-router-view :viewKey="viewKey" :cacheList="cache"/>
- <template #footer>
- <slot name="footer"></slot>
- </template>
- </main-framework>
- </template>
- <script>
- import { computed, ref, watch, provide, reactive } from 'vue'
- import { useCipConfig } from '../hooks/use-cip-config'
- import MainFramework from './framework/framework'
- import CipMainNav from './cip-main-nav'
- import CipMainBreadcrumb from './cip-main-breadcrumb'
- import HeaderBar from './header-bar'
- import CipTabs from './cip-main-tabs'
- import CipRouterView from './cip-router-view'
- import { useRoute } from 'vue-router'
- import { useBadge, useMenuTitle } from './main-hooks'
- import { getFullPathWithoutHash } from './helper'
- export default {
- name: 'Main',
- components: { MainFramework, CipMainNav, HeaderBar, CipMainBreadcrumb, CipTabs, CipRouterView },
- props: {
- logo: String, // 平台LOGO
- platformName: String, // 平台名称
- navMenu: Array, // 导航菜单
- privileges: Array, // 权限
- hideFooter: Boolean, // 是否隐藏footer
- theme: {
- type: String,
- default: 'data-center' // 默认使用数据中台的主题
- // validator: (value) => {
- // return ['data-center', 'light', 'dark'].includes(value)
- // }
- }, // 主题
- layout: {
- type: String,
- default: 'left',
- validator: (value) => {
- return ['left', 'left-2', 'top', 'top-left', 'hide'].includes(value)
- }
- }, // 布局
- withTabs: Boolean, // 是否使用tabs)
- homeView: Object, // 首页配置(开启tabs时建议开启)
- badgeInterval: Number // 获取badge的时间间隔 单位min(分钟)
- },
- setup (props) {
- const cipConfig = useCipConfig()
- const route = useRoute()
- const activeMenu = ref([])
- const cache = ref([])
- const { menuNameMap, menuPathMap } = useMenuTitle()
- // 菜单
- const menu = computed(() => {
- return props.navMenu
- })
- const dynamicMenu = computed(() => {
- if (props.layout !== 'top-left') return menu.value
- if (!activeMenu.value) return []
- // 明确标记没有children时返回当前menu
- if (!activeMenu.value._hasChildren) return [activeMenu.value]
- // 传入当前激活路由top menu的children
- return activeMenu.value.children
- })
- const oneMinute = 60 * 1000
- const { badgeMap, collectBadgeFn, consumptionBadgeFn } = useBadge(props.badgeInterval * oneMinute)
- watch(menu, (val) => {
- collectBadgeFn(val, { key: 'name', fnKey: 'getBadge' })
- }, { immediate: true })
- // 平台名称
- const name = computed(() => {
- return props.platformName ?? process.env.VUE_APP_PLATFORM_NAME
- })
- // 菜单模式
- const navMode = computed(() => {
- return props.layout === 'top' ? 'horizontal' : 'vertical'
- })
- // 兼容KeepAlivePages组件的运行
- const viewKey = computed(() => {
- const routeMatch = route.matched
- const length = routeMatch.length
- const cacheName = length > 1 ? routeMatch[routeMatch.length - 2].name : undefined
- if (cacheName?.indexOf('_cache') > -1) {
- return cacheName
- }
- return cipConfig.withQuery === false ? route.path : getFullPathWithoutHash(route.fullPath)
- })
- const tabsRef = ref()
- const closeTab = () => {
- const fullPath = getFullPathWithoutHash(route.fullPath)
- // eslint-disable-next-line no-unused-expressions
- tabsRef.value?.removeTab(fullPath)
- }
- const handlerPathChange = (fullPath) => {
- fullPath = getFullPathWithoutHash(fullPath)
- // eslint-disable-next-line no-unused-expressions
- tabsRef.value?.handlerPathChange(fullPath)
- }
- provide('closeTab', closeTab)
- provide('pathChange', handlerPathChange)
- provide('cip-menu', reactive({
- menuNameMap,
- navMenu: menu
- }))
- const setChangeSign = () => {
- // const fullPath = getFullPathWithoutHash(route.fullPath)
- }
- provide('setChangeSign', setChangeSign)
- return {
- cache,
- menu,
- name,
- menuNameMap,
- menuPathMap,
- navMode,
- dynamicMenu,
- activeMenu,
- viewKey,
- badgeMap,
- consumptionBadgeFn,
- tabsRef
- }
- }
- }
- </script>
- <style lang="less">
- @import './theme';
- </style>
|