|
@@ -9,9 +9,17 @@
|
|
|
active-text-color="#ffffff"
|
|
active-text-color="#ffffff"
|
|
|
@select="handleSelect"
|
|
@select="handleSelect"
|
|
|
>
|
|
>
|
|
|
- <el-menu-item v-for="(item, index) in topMenus" :key="index" :index="item.path">
|
|
|
|
|
- <svg-icon v-if="item.meta && item.meta.icon" :icon-class="item.meta.icon" />
|
|
|
|
|
- <span>{{ item.meta?.title || item.name }}</span>
|
|
|
|
|
|
|
+ <el-menu-item v-for="(item, index) in topMenus" :key="index" :index="isExternalLink(item) ? `external_${index}` : item.path">
|
|
|
|
|
+ <template v-if="isExternalLink(item)">
|
|
|
|
|
+ <a :href="getExternalUrl(item)" target="_blank" rel="noopener noreferrer" class="external-link" @click.stop>
|
|
|
|
|
+ <svg-icon v-if="item.meta && item.meta.icon" :icon-class="item.meta.icon" />
|
|
|
|
|
+ <span>{{ item.meta?.title || item.name }}</span>
|
|
|
|
|
+ </a>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else>
|
|
|
|
|
+ <svg-icon v-if="item.meta && item.meta.icon" :icon-class="item.meta.icon" />
|
|
|
|
|
+ <span>{{ item.meta?.title || item.name }}</span>
|
|
|
|
|
+ </template>
|
|
|
</el-menu-item>
|
|
</el-menu-item>
|
|
|
</el-menu>
|
|
</el-menu>
|
|
|
</div>
|
|
</div>
|
|
@@ -63,21 +71,43 @@ const setTopMenus = () => {
|
|
|
console.log('TopMenu - 顶部菜单列表:', topMenus.value);
|
|
console.log('TopMenu - 顶部菜单列表:', topMenus.value);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+// 判断是否为外链
|
|
|
|
|
+const isExternalLink = (item: any): boolean => {
|
|
|
|
|
+ // isFrame 为 "0" 表示是外链
|
|
|
|
|
+ return item.isFrame === '0';
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 获取外链完整URL
|
|
|
|
|
+const getExternalUrl = (item: any): string => {
|
|
|
|
|
+ // 对于 isFrame='0' 的外链菜单,path 字段就是完整的外链地址
|
|
|
|
|
+ // 对于内链(isFrame='1' 且 path 是 http 开头),地址存储在 meta.link 中
|
|
|
|
|
+ const url = item.path || item.meta?.link || '';
|
|
|
|
|
+ console.log('TopMenu - 外链地址:', url, '(isFrame:', item.isFrame, ')');
|
|
|
|
|
+ return url;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
// 菜单选择事件
|
|
// 菜单选择事件
|
|
|
const handleSelect = (index: string) => {
|
|
const handleSelect = (index: string) => {
|
|
|
console.log('TopMenu - 选择菜单:', index);
|
|
console.log('TopMenu - 选择菜单:', index);
|
|
|
|
|
|
|
|
- // 清理双斜杠
|
|
|
|
|
- const cleanIndex = index.replace(/\/+/g, '/');
|
|
|
|
|
- console.log('TopMenu - 清理后路径:', cleanIndex);
|
|
|
|
|
|
|
+ // 如果是外链菜单的 index(格式:external_数字),直接返回
|
|
|
|
|
+ if (index.startsWith('external_')) {
|
|
|
|
|
+ console.log('TopMenu - 外链菜单,由 <a> 标签处理打开');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 查找对应的菜单项(支持双斜杠匹配)
|
|
|
|
|
|
|
+ // 查找对应的菜单项
|
|
|
const menuItem = topMenus.value.find((item) => {
|
|
const menuItem = topMenus.value.find((item) => {
|
|
|
const cleanPath = item.path.replace(/\/+/g, '/');
|
|
const cleanPath = item.path.replace(/\/+/g, '/');
|
|
|
|
|
+ const cleanIndex = index.replace(/\/+/g, '/');
|
|
|
return cleanPath === cleanIndex || item.path === index;
|
|
return cleanPath === cleanIndex || item.path === index;
|
|
|
});
|
|
});
|
|
|
console.log('TopMenu - 找到的菜单项:', menuItem);
|
|
console.log('TopMenu - 找到的菜单项:', menuItem);
|
|
|
|
|
|
|
|
|
|
+ // 清理双斜杠
|
|
|
|
|
+ const cleanIndex = index.replace(/\/+/g, '/');
|
|
|
|
|
+ console.log('TopMenu - 清理后路径:', cleanIndex);
|
|
|
|
|
+
|
|
|
if (menuItem) {
|
|
if (menuItem) {
|
|
|
// 判断是否有子菜单(过滤掉隐藏的和按钮类型的)
|
|
// 判断是否有子菜单(过滤掉隐藏的和按钮类型的)
|
|
|
const hasChildren = menuItem.children && menuItem.children.length > 0;
|
|
const hasChildren = menuItem.children && menuItem.children.length > 0;
|
|
@@ -182,6 +212,24 @@ watch(
|
|
|
span {
|
|
span {
|
|
|
vertical-align: middle;
|
|
vertical-align: middle;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ .external-link {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ color: inherit;
|
|
|
|
|
+ text-decoration: none;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ color: #ffffff;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .svg-icon {
|
|
|
|
|
+ margin-right: 8px;
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|