| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- <template>
- <div style="height: 100%; width: 100%; display: flex; flex-direction: row;">
- <!-- 左边是列表 -->
- <div style="width: 300px; height: 100%;">
- <el-card style="height: 100%;">
- <template #header>
- <div class="card-header">
- <el-icon :size="15" class="mr-2" style="vertical-align: middle;">
- <component :is="Menu" />
- </el-icon>
- <span>项目列表</span>
- </div>
- </template>
- <el-menu
- :key="menuKey"
- :default-active="activePath"
- :default-openeds="defaultOpeneds"
- class="custom-menu"
- mode="vertical"
- @select="handleMenuSelect"
- >
- <el-sub-menu
- v-for="(parent, parentIndex) in menuItems"
- :key="parentIndex"
- :index="parent.index"
- :class="{ 'parent-active': isParentActive(parent.index) }"
- >
- <template #title>
- <!-- 父菜单图标 -->
- <el-icon :size="18" class="mr-2">
- <component :is="parent.icon" />
- </el-icon>
- <span>{{ parent.title }}</span>
- </template>
- <el-menu-item
- v-for="(child, childIndex) in parent.children"
- :key="childIndex"
- :index="child.index"
- >
- <!-- 子菜单图标 -->
- <el-icon :size="18" class="mr-2">
- <component :is="child.icon" />
- </el-icon>
- <span>{{ child.title }}</span>
- </el-menu-item>
- </el-sub-menu>
- </el-menu>
- </el-card>
- </div>
- <!-- 右边是地图引擎 -->
- <map-editor ref="mapEditor" :refname="'rtWatch'" id="me" class="map-editor" ></map-editor>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, onMounted, computed, onUnmounted } from "vue";
- import MapEditor from '@/components/MapEditor/index.vue'
- // 导入 Element Plus 内置图标
- import {
- Folder,
- Menu,
- } from '@element-plus/icons-vue';
- const mapEditor = ref(null)
- const vGlobal = window.vueGlobal;
- // 菜单数据
- const menuItems = [
- {
- index: '1',
- title: '父菜单1',
- icon: Menu,
- children: [
- { index: '1-1', title: '子菜单1-1', icon: Folder }
- ]
- }
- ];
- const menuKey = ref(0);
- let dictMenus = {};
- // 当前选中的路径
- const activePath = ref('');
- // 计算所有父菜单的索引,用于默认展开所有子菜单
- const defaultOpeneds = computed(() => {
- // 提取所有父菜单的 index 组成数组
- return menuItems.map(item => item.index);
- });
- let scheduleId = null;
- const createMenus = () => {
- menuItems.splice(0);
- dictMenus = {};
- for (const p of vGlobal.vecProject) {
- const pIdx = '' + p.id;
- menuItems.push({
- index: pIdx,
- title: p.name,
- icon: Menu,
- children: []
- });
- dictMenus[pIdx] = p;
- for (const m of p.locations) {
- const mIdx = pIdx + '-' + m.id;
- menuItems[menuItems.length - 1].children.push({
- index: mIdx,
- title: m.name,
- icon: Folder
- });
- dictMenus[mIdx] = m;
- }
- }
- menuKey.value++;
- };
- // 处理菜单选中事件
- const handleMenuSelect = (index) => {
- activePath.value = index;
- console.log('handleMenuSelect', index, dictMenus[index]);
- const location = dictMenus[index];
- if (location) {
- vGlobal.mapEngine.focusPt(location.center.x, location.center.y);
- }
- };
- // 判断父菜单是否需要激活样式
- const isParentActive = (parentIndex) => {
- // 检查当前选中项是否属于该父菜单
- return activePath.value.startsWith(parentIndex + '-');
- };
- const handleOpen = (key: string, keyPath: string[]) => {
- console.log(key, keyPath)
- }
- const handleClose = (key: string, keyPath: string[]) => {
- console.log(key, keyPath)
- }
- const schedule = () => {
- if (!vGlobal.isInited()) {
- return;
- }
- console.log('schedule loop' + new Date().toLocaleTimeString());
- };
- onMounted(() => {
- const ci = setInterval(() => {
- if (vGlobal.isInited()) {
- clearInterval(ci);
- createMenus();
- }
- }, 100);
- console.log('onMounted');
- scheduleId = setInterval(() => {
- schedule();
- }, 1000);
- });
- onUnmounted(() => {
- clearInterval(scheduleId);
- console.log('onUnmounted');
- scheduleId = null;
- });
- </script>
- <style scoped>
- .custom-menu {
- width: 100%;
- }
- :deep(.el-sub-menu .el-menu-item.is-active) {
- color: #0557aa !important;
- background-color: #e6f7ff !important;
- }
- /* 子菜单选中样式 */
- :deep(.el-menu-item.is-active) {
- color: #0557aa !important;
- background-color: #e6f7ff !important;
- font-weight: 600;
- }
- /* 父菜单激活样式 - 当子菜单选中时 */
- :deep(.parent-active .el-sub-menu__title) {
- color: #0557aa !important;
- font-weight: bold;
- }
- /* 父菜单 hover 样式保持一致 */
- :deep(.el-sub-menu__title:hover) {
- color: #0557aa !important;
- }
- </style>
|