|
|
@@ -0,0 +1,99 @@
|
|
|
+<template>
|
|
|
+ <template v-if="!item.hidden" >
|
|
|
+ <template
|
|
|
+ v-if="hasOneShowingChild(item.children, item)"
|
|
|
+ >
|
|
|
+ <a-menu-item :key="item.path" @click="changeRoute(item)" >
|
|
|
+ <user-outlined />
|
|
|
+ <span>{{item.name}}</span>
|
|
|
+ </a-menu-item>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <a-sub-menu v-else>
|
|
|
+ <template #title>
|
|
|
+ <user-outlined />
|
|
|
+ <span>
|
|
|
+ {{item.name}}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ <sidebar-item
|
|
|
+ v-for="child in item.children"
|
|
|
+ :key="child.path"
|
|
|
+ :item="child"
|
|
|
+ :base-path="resolvePath(child.path)"
|
|
|
+ />
|
|
|
+ </a-sub-menu>
|
|
|
+ </template>
|
|
|
+</template>
|
|
|
+<!-- :base-path="resolvePath(child.path)" -->
|
|
|
+
|
|
|
+<script setup lang="ts" >
|
|
|
+import path from 'path-browserify'
|
|
|
+import { reactive, toRefs } from 'vue'
|
|
|
+import { useRouter } from 'vue-router'
|
|
|
+import { MenuFoldOutlined, MenuUnfoldOutlined, UserOutlined } from '@ant-design/icons-vue'
|
|
|
+
|
|
|
+const RootRouter = useRouter()
|
|
|
+const props = defineProps({
|
|
|
+ // 每一个router Item
|
|
|
+ item: {
|
|
|
+ type: Object,
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ // 基础路径,用于拼接
|
|
|
+ basePath: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const changeRoute = (route: ROUTER.RoutesProps) => {
|
|
|
+ RootRouter.push(route.path)
|
|
|
+}
|
|
|
+
|
|
|
+const state = reactive({
|
|
|
+ onlyOneChild: null
|
|
|
+})
|
|
|
+
|
|
|
+const { onlyOneChild } = toRefs(state)
|
|
|
+
|
|
|
+const hasOneShowingChild = (children = [], parent: any) => {
|
|
|
+ const showingChildren = children.filter((item) => {
|
|
|
+ if (item.hidden) {
|
|
|
+ return false
|
|
|
+ } else {
|
|
|
+ state.onlyOneChild = item
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ if (showingChildren.length === 1) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ if (showingChildren.length === 0) {
|
|
|
+ state.onlyOneChild = { ...parent, path: '', noShowingChildren: true }
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+function isExternal (path: string) {
|
|
|
+ return /^(https?:|mailto:|tel:)/.test(path)
|
|
|
+}
|
|
|
+
|
|
|
+const resolvePath = (routePath: string) => {
|
|
|
+ if (isExternal(routePath)) {
|
|
|
+ return routePath
|
|
|
+ }
|
|
|
+ if (isExternal(props.basePath)) {
|
|
|
+ return props.basePath
|
|
|
+ }
|
|
|
+ return path.resolve(props.basePath, routePath)
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" >
|
|
|
+
|
|
|
+</style>
|