feat: 面包屑组件
This commit is contained in:
parent
4c40c96383
commit
bd0e71d77b
308
packages/screen/src/component/Breadcrumb/index.vue
Normal file
308
packages/screen/src/component/Breadcrumb/index.vue
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
<template>
|
||||||
|
<div class="breadcrumb-container">
|
||||||
|
<el-breadcrumb separator="/">
|
||||||
|
<el-breadcrumb-item
|
||||||
|
v-for="(item, index) in breadcrumbList"
|
||||||
|
:key="index"
|
||||||
|
:class="{ 'is-link': index < breadcrumbList.length - 1 }"
|
||||||
|
@click="handleBreadcrumbClick(item, index)"
|
||||||
|
>
|
||||||
|
{{ item.title }}
|
||||||
|
</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
|
||||||
|
<!-- 关闭按钮组 -->
|
||||||
|
<div class="breadcrumb-actions" v-if="breadcrumbList.length > 1">
|
||||||
|
<el-dropdown trigger="click" @command="handleCloseAction">
|
||||||
|
<el-button type="text" size="small" class="close-btn">
|
||||||
|
<el-icon><Close /></el-icon>
|
||||||
|
关闭
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item command="close-current">关闭当前页</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="close-other" :disabled="breadcrumbList.length <= 2">关闭其他页</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="close-left" :disabled="currentIndex === 0">关闭左侧</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="close-right" :disabled="currentIndex === breadcrumbList.length - 1">关闭右侧</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="close-all" :disabled="breadcrumbList.length <= 1">全部关闭</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch, onMounted } from 'vue'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import { Close } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
homeTitle: {
|
||||||
|
type: String,
|
||||||
|
default: '首页'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['breadcrumb-change'])
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
const breadcrumbList = ref([])
|
||||||
|
const currentIndex = ref(0)
|
||||||
|
|
||||||
|
// 路由配置映射表(用于查找父级路由)
|
||||||
|
const routeMap = {
|
||||||
|
'warningManagement': {
|
||||||
|
path: '/warningManagement',
|
||||||
|
name: 'warningManagement',
|
||||||
|
meta: { title: '响应预警' }
|
||||||
|
},
|
||||||
|
'ledgerManagement': {
|
||||||
|
path: '/ledgerManagement',
|
||||||
|
name: 'ledgerManagement',
|
||||||
|
meta: { title: '驻地台账' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成面包屑数据
|
||||||
|
const generateBreadcrumb = () => {
|
||||||
|
const matched = route.matched.filter(item => item.meta && item.meta.breadcrumb !== false)
|
||||||
|
|
||||||
|
// 基础面包屑:首页
|
||||||
|
breadcrumbList.value = [
|
||||||
|
{
|
||||||
|
title: props.homeTitle,
|
||||||
|
path: '/',
|
||||||
|
name: 'Home'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const currentPath = route.path
|
||||||
|
|
||||||
|
// 特殊处理:驻地台账页面(响应预警的子页面)
|
||||||
|
if (currentPath.includes('/ledgerManagement')) {
|
||||||
|
// 添加响应预警(父级)
|
||||||
|
breadcrumbList.value.push({
|
||||||
|
title: '响应预警',
|
||||||
|
path: '/warningManagement',
|
||||||
|
name: 'warningManagement',
|
||||||
|
meta: { title: '响应预警' }
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加驻地台账(当前页)
|
||||||
|
breadcrumbList.value.push({
|
||||||
|
title: '驻地台账',
|
||||||
|
path: currentPath,
|
||||||
|
name: 'ledgerManagement',
|
||||||
|
meta: { title: '驻地台账' }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 普通路由处理
|
||||||
|
matched.forEach((record, index) => {
|
||||||
|
// 跳过根路径(已经在上面添加了首页)
|
||||||
|
if (record.path === '/') return
|
||||||
|
|
||||||
|
if (record.meta && record.meta.title) {
|
||||||
|
let fullPath = record.path
|
||||||
|
|
||||||
|
// 处理相对路径
|
||||||
|
if (!fullPath.startsWith('/') && index > 0) {
|
||||||
|
const parentPath = breadcrumbList.value[breadcrumbList.value.length - 1]?.path || ''
|
||||||
|
if (parentPath) {
|
||||||
|
fullPath = parentPath + (parentPath.endsWith('/') ? '' : '/') + record.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
breadcrumbList.value.push({
|
||||||
|
title: record.meta.title,
|
||||||
|
path: fullPath,
|
||||||
|
name: record.name,
|
||||||
|
meta: record.meta
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新当前索引
|
||||||
|
const currentIndexInList = breadcrumbList.value.findIndex(item => item.path === currentPath)
|
||||||
|
currentIndex.value = currentIndexInList >= 0 ? currentIndexInList : breadcrumbList.value.length - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理面包屑点击
|
||||||
|
const handleBreadcrumbClick = (item, index) => {
|
||||||
|
if (index < breadcrumbList.value.length - 1) {
|
||||||
|
router.push(item.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理关闭操作
|
||||||
|
const handleCloseAction = (command) => {
|
||||||
|
switch (command) {
|
||||||
|
case 'close-current':
|
||||||
|
closeCurrentPage()
|
||||||
|
break
|
||||||
|
case 'close-other':
|
||||||
|
closeOtherPages()
|
||||||
|
break
|
||||||
|
case 'close-left':
|
||||||
|
closeLeftPages()
|
||||||
|
break
|
||||||
|
case 'close-right':
|
||||||
|
closeRightPages()
|
||||||
|
break
|
||||||
|
case 'close-all':
|
||||||
|
closeAllPages()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭当前页
|
||||||
|
const closeCurrentPage = () => {
|
||||||
|
if (breadcrumbList.value.length <= 1) return
|
||||||
|
|
||||||
|
const currentPath = route.path
|
||||||
|
const currentIndex = breadcrumbList.value.findIndex(item => item.path === currentPath)
|
||||||
|
|
||||||
|
if (currentIndex > 0) {
|
||||||
|
// 跳转到前一个页面
|
||||||
|
const prevPage = breadcrumbList.value[currentIndex - 1]
|
||||||
|
breadcrumbList.value.splice(currentIndex, 1)
|
||||||
|
router.push(prevPage.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭其他页
|
||||||
|
const closeOtherPages = () => {
|
||||||
|
if (breadcrumbList.value.length <= 2) return
|
||||||
|
|
||||||
|
const currentPath = route.path
|
||||||
|
const currentItem = breadcrumbList.value.find(item => item.path === currentPath)
|
||||||
|
|
||||||
|
if (currentItem) {
|
||||||
|
breadcrumbList.value = [
|
||||||
|
breadcrumbList.value[0], // 保留首页
|
||||||
|
currentItem
|
||||||
|
]
|
||||||
|
|
||||||
|
// 触发路由跳转逻辑
|
||||||
|
emit('breadcrumb-change', breadcrumbList.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭左侧页
|
||||||
|
const closeLeftPages = () => {
|
||||||
|
if (currentIndex.value <= 1) return
|
||||||
|
|
||||||
|
const currentItem = breadcrumbList.value[currentIndex.value]
|
||||||
|
breadcrumbList.value = [
|
||||||
|
breadcrumbList.value[0], // 保留首页
|
||||||
|
currentItem
|
||||||
|
]
|
||||||
|
|
||||||
|
// 如果当前不在首页,需要重新构建路径
|
||||||
|
let targetPath = '/'
|
||||||
|
if (currentItem.path !== '/') {
|
||||||
|
targetPath = currentItem.path
|
||||||
|
}
|
||||||
|
router.push(targetPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭右侧页
|
||||||
|
const closeRightPages = () => {
|
||||||
|
if (currentIndex.value >= breadcrumbList.value.length - 1) return
|
||||||
|
|
||||||
|
breadcrumbList.value = breadcrumbList.value.slice(0, currentIndex.value + 1)
|
||||||
|
|
||||||
|
// 跳转到最后一个保留的页面
|
||||||
|
const lastItem = breadcrumbList.value[breadcrumbList.value.length - 1]
|
||||||
|
router.push(lastItem.path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭所有页(回到首页)
|
||||||
|
const closeAllPages = () => {
|
||||||
|
breadcrumbList.value = [breadcrumbList.value[0]]
|
||||||
|
router.push('/')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听路由变化
|
||||||
|
watch(() => route.path, () => {
|
||||||
|
generateBreadcrumb()
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
generateBreadcrumb()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
breadcrumbList,
|
||||||
|
refreshBreadcrumb: generateBreadcrumb
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.breadcrumb-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 16px;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border-bottom: 1px solid #e4e7ed;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
:deep(.el-breadcrumb) {
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
.el-breadcrumb__item {
|
||||||
|
.el-breadcrumb__inner {
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
&.is-link {
|
||||||
|
color: #409eff;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #66b1ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child .el-breadcrumb__inner {
|
||||||
|
color: #303133;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.close-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -5,41 +5,65 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
component: () => import('../views/Home.vue')
|
component: () => import('../views/Home.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '首页',
|
||||||
|
breadcrumb: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/cockpit',
|
path: '/cockpit',
|
||||||
name: 'Cockpit',
|
name: 'Cockpit',
|
||||||
meta: {
|
meta: {
|
||||||
screen: true
|
title: '驾驶舱',
|
||||||
|
screen: true,
|
||||||
|
breadcrumb: true
|
||||||
},
|
},
|
||||||
component: () => import('../views/cockpit/index.vue')
|
component: () => import('../views/cockpit/index.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/yhz',
|
path: '/yhz',
|
||||||
name: 'yhz',
|
name: 'yhz',
|
||||||
component: () => import('../views/ServiceStationManagePage/index.vue')
|
component: () => import('../views/ServiceStationManagePage/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '养护站管理',
|
||||||
|
breadcrumb: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/yhzsb/:data?',
|
path: '/yhzsb/:data?',
|
||||||
name: 'yhzsb',
|
name: 'yhzsb',
|
||||||
component: () => import('../views/EquipmentManagement/index.vue')
|
component: () => import('../views/EquipmentManagement/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '养护站设备',
|
||||||
|
breadcrumb: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/yhzwz/:data?',
|
path: '/yhzwz/:data?',
|
||||||
name: 'yhzwz',
|
name: 'yhzwz',
|
||||||
component: () => import('../views/MaterialManagement/index.vue')
|
component: () => import('../views/MaterialManagement/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '养护站物资',
|
||||||
|
breadcrumb: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/yhzevent',
|
path: '/yhzevent',
|
||||||
name: 'yhzevent',
|
name: 'yhzevent',
|
||||||
component: () => import('../views/SnowEventManagement/index.vue')
|
component: () => import('../views/SnowEventManagement/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '雪情事件管理',
|
||||||
|
breadcrumb: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/airSkyLand',
|
path: '/airSkyLand',
|
||||||
name: 'airskyland',
|
name: 'airskyland',
|
||||||
meta: {
|
meta: {
|
||||||
screen: true
|
title: '空天地一体化',
|
||||||
|
screen: true,
|
||||||
|
breadcrumb: true
|
||||||
},
|
},
|
||||||
component: () => import('../views/airSkyLand/AirSkyLand.vue')
|
component: () => import('../views/airSkyLand/AirSkyLand.vue')
|
||||||
|
|
||||||
@ -48,8 +72,10 @@ const routes = [
|
|||||||
path: '/3DSituationalAwareness',
|
path: '/3DSituationalAwareness',
|
||||||
name: '3DSituationalAwareness',
|
name: '3DSituationalAwareness',
|
||||||
meta: {
|
meta: {
|
||||||
|
title: '三维态势感知',
|
||||||
screen: true,
|
screen: true,
|
||||||
skipInitialCameraView: true // 跳过MapViewport的自动初始视图,由页面自己控制相机
|
skipInitialCameraView: true, // 跳过MapViewport的自动初始视图,由页面自己控制相机
|
||||||
|
breadcrumb: true
|
||||||
},
|
},
|
||||||
component: () => import('../views/3DSituationalAwarenessRefactor/index.vue')
|
component: () => import('../views/3DSituationalAwarenessRefactor/index.vue')
|
||||||
},
|
},
|
||||||
@ -57,7 +83,9 @@ const routes = [
|
|||||||
path: '/riskWarning',
|
path: '/riskWarning',
|
||||||
name: 'RiskWarning',
|
name: 'RiskWarning',
|
||||||
meta: {
|
meta: {
|
||||||
screen: true
|
title: '风险预警',
|
||||||
|
screen: true,
|
||||||
|
breadcrumb: true
|
||||||
},
|
},
|
||||||
component: () => import('../views/RiskWarning/index.vue')
|
component: () => import('../views/RiskWarning/index.vue')
|
||||||
},
|
},
|
||||||
@ -65,7 +93,9 @@ const routes = [
|
|||||||
path: '/regulationsDivision',
|
path: '/regulationsDivision',
|
||||||
name: 'RegulationsDivision',
|
name: 'RegulationsDivision',
|
||||||
meta: {
|
meta: {
|
||||||
screen: true
|
title: '法规分工',
|
||||||
|
screen: true,
|
||||||
|
breadcrumb: true
|
||||||
},
|
},
|
||||||
component: () => import('../views/RegulationsDivision/RegulationsDivision.vue')
|
component: () => import('../views/RegulationsDivision/RegulationsDivision.vue')
|
||||||
},
|
},
|
||||||
@ -73,7 +103,9 @@ const routes = [
|
|||||||
path: '/warningCounty',
|
path: '/warningCounty',
|
||||||
name: 'WarningCounty',
|
name: 'WarningCounty',
|
||||||
meta: {
|
meta: {
|
||||||
screen: true
|
title: '区县预警',
|
||||||
|
screen: true,
|
||||||
|
breadcrumb: true
|
||||||
},
|
},
|
||||||
component: () => import('../views/warningCounty/warningCounty.vue')
|
component: () => import('../views/warningCounty/warningCounty.vue')
|
||||||
},
|
},
|
||||||
@ -81,7 +113,9 @@ const routes = [
|
|||||||
path: '/constructionDepartment',
|
path: '/constructionDepartment',
|
||||||
name: 'ConstructionDepartment',
|
name: 'ConstructionDepartment',
|
||||||
meta: {
|
meta: {
|
||||||
screen: true
|
title: '建设部门',
|
||||||
|
screen: true,
|
||||||
|
breadcrumb: true
|
||||||
},
|
},
|
||||||
component: () => import('../views/ConstructionDepartment/ConstructionDepartment.vue')
|
component: () => import('../views/ConstructionDepartment/ConstructionDepartment.vue')
|
||||||
},
|
},
|
||||||
@ -89,14 +123,23 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: '/warningManagement',
|
path: '/warningManagement',
|
||||||
name: 'warningManagement',
|
name: 'warningManagement',
|
||||||
component: () => import('../views/WarningManagement/index.vue')
|
component: () => import('../views/WarningManagement/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '响应预警',
|
||||||
|
breadcrumb: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// 驻地台账
|
// 驻地台账 - 作为独立的页面,但在面包屑中显示为响应预警的子页面
|
||||||
{
|
{
|
||||||
path: '/ledgerManagement',
|
path: '/ledgerManagement',
|
||||||
name: 'ledgerManagement',
|
name: 'ledgerManagement',
|
||||||
component: () => import('../views/LedgerManagement/index.vue')
|
component: () => import('../views/LedgerManagement/index.vue'),
|
||||||
},
|
meta: {
|
||||||
|
title: '驻地台账',
|
||||||
|
breadcrumb: true,
|
||||||
|
parentRoute: 'warningManagement' // 用于在面包屑中建立父子关系
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|||||||
@ -189,7 +189,7 @@ export default () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const gotoLedgerPage = () => {
|
const gotoLedgerPage = () => {
|
||||||
router.push({
|
router.push({
|
||||||
path: `/ledgerManagement`,
|
path: '/ledgerManagement'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,12 @@
|
|||||||
<MenuBar></MenuBar>
|
<MenuBar></MenuBar>
|
||||||
</div>
|
</div>
|
||||||
<div class="content-main">
|
<div class="content-main">
|
||||||
<router-view></router-view>
|
<div class="breadcrumb-wrapper">
|
||||||
|
<Breadcrumb ref="breadcrumbRef" @breadcrumb-change="handleBreadcrumbChange"></Breadcrumb>
|
||||||
|
</div>
|
||||||
|
<div class="router-wrapper">
|
||||||
|
<router-view></router-view>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -20,7 +25,15 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import MenuBar from "../component/MenuBar/index.vue";
|
import MenuBar from "../component/MenuBar/index.vue";
|
||||||
import {User} from '@element-plus/icons-vue'
|
import Breadcrumb from '../component/Breadcrumb/index.vue';
|
||||||
|
import { User } from '@element-plus/icons-vue'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const breadcrumbRef = ref(null)
|
||||||
|
|
||||||
|
const handleBreadcrumbChange = (breadcrumbList) => {
|
||||||
|
console.log('面包屑变更:', breadcrumbList)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -65,5 +78,20 @@ import {User} from '@element-plus/icons-vue'
|
|||||||
.content-main {
|
.content-main {
|
||||||
width: calc(100% - 248px);
|
width: calc(100% - 248px);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.breadcrumb-wrapper {
|
||||||
|
height: 40px;
|
||||||
|
min-height: 40px;
|
||||||
|
width: 100%;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border-bottom: 1px solid #e4e7ed;
|
||||||
|
}
|
||||||
|
.router-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
height: calc(100% - 40px);
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Loading…
x
Reference in New Issue
Block a user