mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	Merge branch 'main' into gitee
This commit is contained in:
		
						commit
						97cb48e726
					
				
							
								
								
									
										36
									
								
								src/layout/components/sidebar/linkItem.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/layout/components/sidebar/linkItem.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { computed } from "vue";
 | 
				
			||||||
 | 
					import { isUrl } from "@pureadmin/utils";
 | 
				
			||||||
 | 
					import { menuType } from "@/layout/types";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defineOptions({
 | 
				
			||||||
 | 
					  name: "LinkItem"
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = defineProps<{
 | 
				
			||||||
 | 
					  to: menuType;
 | 
				
			||||||
 | 
					}>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const isExternalLink = computed(() => isUrl(props.to.name));
 | 
				
			||||||
 | 
					const getLinkProps = (item: menuType) => {
 | 
				
			||||||
 | 
					  if (isExternalLink.value) {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      href: item.name,
 | 
				
			||||||
 | 
					      target: "_blank",
 | 
				
			||||||
 | 
					      rel: "noopener"
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    to: item
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <component
 | 
				
			||||||
 | 
					    :is="isExternalLink ? 'a' : 'router-link'"
 | 
				
			||||||
 | 
					    v-bind="getLinkProps(to)"
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
 | 
					    <slot />
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
@ -48,6 +48,7 @@ const { title, getLogo } = useNav();
 | 
				
			|||||||
    flex-wrap: nowrap;
 | 
					    flex-wrap: nowrap;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
    height: 100%;
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    padding-left: 10px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    img {
 | 
					    img {
 | 
				
			||||||
      display: inline-block;
 | 
					      display: inline-block;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,19 +1,28 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import path from "path";
 | 
					import path from "path";
 | 
				
			||||||
import { getConfig } from "@/config";
 | 
					import { getConfig } from "@/config";
 | 
				
			||||||
 | 
					import LinkItem from "./linkItem.vue";
 | 
				
			||||||
import { menuType } from "../../types";
 | 
					import { menuType } from "../../types";
 | 
				
			||||||
import extraIcon from "./extraIcon.vue";
 | 
					import extraIcon from "./extraIcon.vue";
 | 
				
			||||||
import { ReText } from "@/components/ReText";
 | 
					import { ReText } from "@/components/ReText";
 | 
				
			||||||
import { useNav } from "@/layout/hooks/useNav";
 | 
					import { useNav } from "@/layout/hooks/useNav";
 | 
				
			||||||
import { transformI18n } from "@/plugins/i18n";
 | 
					import { transformI18n } from "@/plugins/i18n";
 | 
				
			||||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 | 
					import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 | 
				
			||||||
import { type CSSProperties, type PropType, computed, ref, toRaw } from "vue";
 | 
					import {
 | 
				
			||||||
 | 
					  type PropType,
 | 
				
			||||||
 | 
					  type CSSProperties,
 | 
				
			||||||
 | 
					  ref,
 | 
				
			||||||
 | 
					  toRaw,
 | 
				
			||||||
 | 
					  computed,
 | 
				
			||||||
 | 
					  useAttrs
 | 
				
			||||||
 | 
					} from "vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ArrowUp from "@iconify-icons/ep/arrow-up-bold";
 | 
					import ArrowUp from "@iconify-icons/ep/arrow-up-bold";
 | 
				
			||||||
import EpArrowDown from "@iconify-icons/ep/arrow-down-bold";
 | 
					import EpArrowDown from "@iconify-icons/ep/arrow-down-bold";
 | 
				
			||||||
import ArrowLeft from "@iconify-icons/ep/arrow-left-bold";
 | 
					import ArrowLeft from "@iconify-icons/ep/arrow-left-bold";
 | 
				
			||||||
import ArrowRight from "@iconify-icons/ep/arrow-right-bold";
 | 
					import ArrowRight from "@iconify-icons/ep/arrow-right-bold";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const attrs = useAttrs();
 | 
				
			||||||
const { layout, isCollapse, tooltipEffect, getDivStyle } = useNav();
 | 
					const { layout, isCollapse, tooltipEffect, getDivStyle } = useNav();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
@ -32,6 +41,7 @@ const props = defineProps({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const getNoDropdownStyle = computed((): CSSProperties => {
 | 
					const getNoDropdownStyle = computed((): CSSProperties => {
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
 | 
					    width: "100%",
 | 
				
			||||||
    display: "flex",
 | 
					    display: "flex",
 | 
				
			||||||
    alignItems: "center"
 | 
					    alignItems: "center"
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
@ -96,14 +106,18 @@ function resolvePath(routePath) {
 | 
				
			|||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <el-menu-item
 | 
					  <link-item
 | 
				
			||||||
    v-if="
 | 
					    v-if="
 | 
				
			||||||
      hasOneShowingChild(props.item.children, props.item) &&
 | 
					      hasOneShowingChild(props.item.children, props.item) &&
 | 
				
			||||||
      (!onlyOneChild.children || onlyOneChild.noShowingChildren)
 | 
					      (!onlyOneChild.children || onlyOneChild.noShowingChildren)
 | 
				
			||||||
    "
 | 
					    "
 | 
				
			||||||
 | 
					    :to="item"
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
 | 
					    <el-menu-item
 | 
				
			||||||
      :index="resolvePath(onlyOneChild.path)"
 | 
					      :index="resolvePath(onlyOneChild.path)"
 | 
				
			||||||
      :class="{ 'submenu-title-noDropdown': !isNest }"
 | 
					      :class="{ 'submenu-title-noDropdown': !isNest }"
 | 
				
			||||||
      :style="getNoDropdownStyle"
 | 
					      :style="getNoDropdownStyle"
 | 
				
			||||||
 | 
					      v-bind="attrs"
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <div
 | 
					      <div
 | 
				
			||||||
        v-if="toRaw(props.item.meta.icon)"
 | 
					        v-if="toRaw(props.item.meta.icon)"
 | 
				
			||||||
@ -151,6 +165,7 @@ function resolvePath(routePath) {
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </template>
 | 
					      </template>
 | 
				
			||||||
    </el-menu-item>
 | 
					    </el-menu-item>
 | 
				
			||||||
 | 
					  </link-item>
 | 
				
			||||||
  <el-sub-menu
 | 
					  <el-sub-menu
 | 
				
			||||||
    v-else
 | 
					    v-else
 | 
				
			||||||
    ref="subMenu"
 | 
					    ref="subMenu"
 | 
				
			||||||
 | 
				
			|||||||
@ -62,6 +62,7 @@ export interface setType {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export type menuType = {
 | 
					export type menuType = {
 | 
				
			||||||
  id?: number;
 | 
					  id?: number;
 | 
				
			||||||
 | 
					  name?: string;
 | 
				
			||||||
  path?: string;
 | 
					  path?: string;
 | 
				
			||||||
  noShowingChildren?: boolean;
 | 
					  noShowingChildren?: boolean;
 | 
				
			||||||
  children?: menuType[];
 | 
					  children?: menuType[];
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,11 @@
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* 修复 windows 下双滚动条问题 https://github.com/pure-admin/vue-pure-admin/pull/936#issuecomment-1968125992 */
 | 
				
			||||||
 | 
					  .el-popper.pure-scrollbar {
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* popper menu 超出内容区可滚动 */
 | 
					  /* popper menu 超出内容区可滚动 */
 | 
				
			||||||
  .pure-scrollbar {
 | 
					  .pure-scrollbar {
 | 
				
			||||||
    max-height: calc(100vh - calc(50px * 2.5));
 | 
					    max-height: calc(100vh - calc(50px * 2.5));
 | 
				
			||||||
@ -130,11 +135,9 @@
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    a {
 | 
					    a {
 | 
				
			||||||
      display: inline-block;
 | 
					 | 
				
			||||||
      display: flex;
 | 
					      display: flex;
 | 
				
			||||||
      flex-wrap: wrap;
 | 
					      flex-wrap: wrap;
 | 
				
			||||||
      width: 100%;
 | 
					      width: 100%;
 | 
				
			||||||
      padding-left: 10px;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .el-menu {
 | 
					    .el-menu {
 | 
				
			||||||
@ -332,9 +335,18 @@
 | 
				
			|||||||
      margin-top: 0;
 | 
					      margin-top: 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* 无子菜单时激活 border-bottom */
 | 
				
			||||||
 | 
					    a > .is-active.submenu-title-noDropdown {
 | 
				
			||||||
 | 
					      border-bottom: 2px solid var(--el-menu-active-color);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .el-menu--popup {
 | 
					    .el-menu--popup {
 | 
				
			||||||
      background-color: $subMenuBg !important;
 | 
					      background-color: $subMenuBg !important;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      a > .is-active.submenu-title-noDropdown {
 | 
				
			||||||
 | 
					        border-bottom: none;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      .el-menu-item {
 | 
					      .el-menu-item {
 | 
				
			||||||
        color: $menuText;
 | 
					        color: $menuText;
 | 
				
			||||||
        background-color: $subMenuBg;
 | 
					        background-color: $subMenuBg;
 | 
				
			||||||
@ -349,12 +361,6 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 无子菜单时激活 border-bottom */
 | 
					 | 
				
			||||||
    .router-link-exact-active > .submenu-title-noDropdown {
 | 
					 | 
				
			||||||
      height: 60px;
 | 
					 | 
				
			||||||
      border-bottom: 2px solid var(--el-menu-active-color);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* 子菜单中还有子菜单 */
 | 
					    /* 子菜单中还有子菜单 */
 | 
				
			||||||
    .el-menu .el-sub-menu__title {
 | 
					    .el-menu .el-sub-menu__title {
 | 
				
			||||||
      min-width: $sideBarWidth !important;
 | 
					      min-width: $sideBarWidth !important;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user