forked from mengyxu/noob-components
Browse Source
- Update env files and vite config for development setup - Menu tree changes for menu handling Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>dev
4 changed files with 117 additions and 78 deletions
@ -1,3 +1,4 @@ |
|||||||
# VUE_APP_BASE_URL="http://172.16.16.120:8080" |
# VUE_APP_BASE_URL="http://172.16.16.120:8080" |
||||||
# VUE_APP_BASE_URL="http://10.100.0.108:8082" |
# VUE_APP_BASE_URL="http://10.100.0.108:8082" |
||||||
VUE_APP_BASE_URL="http://localhost:80" |
VUE_APP_BASE_URL="http://localhost:80" |
||||||
|
VITE_APP_VERSION=$npm_package_version |
||||||
|
|||||||
@ -1,2 +1,3 @@ |
|||||||
NODE_ENV="production" |
NODE_ENV="production" |
||||||
VUE_APP_BASE_URL="" |
VUE_APP_BASE_URL="" |
||||||
|
VITE_APP_VERSION=$npm_package_version |
||||||
|
|||||||
@ -1,122 +1,157 @@ |
|||||||
<template> |
<template> |
||||||
<el-menu :default-active="active" router :mode="mode" :class="mode" :text-color="state.style.menuColor" |
<div class="menu-container"> |
||||||
:background-color="mode == 'horizontal' ? state.style.headBg : state.style.menuBg" |
<el-menu |
||||||
:active-text-color="state.style.menuActiveColor" :size="state.size.size"> |
:default-active="active" |
||||||
<div class="title" v-if="title"> |
router |
||||||
<el-image class="logo" v-if="logo" :src="logo" fit="fit" /> |
:mode="mode" |
||||||
{{ title || t('title') }} |
:class="mode" |
||||||
</div> |
:text-color="state.style.menuColor" |
||||||
<template v-for="menu in data || state.menus"> |
:background-color="mode == 'horizontal' ? state.style.headBg : state.style.menuBg" |
||||||
<template v-if="menu.children && menu.children.length > 0"> |
:active-text-color="state.style.menuActiveColor" |
||||||
<el-sub-menu :index="getPath(menu)" :key="menu.path"> |
:size="state.size.size" |
||||||
<template #title> |
> |
||||||
<component class="icon" :is="menu.icon || state.style.menuDefaultIcon"> |
<div class="title" v-if="title"> |
||||||
</component> |
<el-image class="logo" v-if="logo" :src="logo" fit="fit" /> |
||||||
<span>{{ menu.title || t(menu.i18n) }}</span> |
{{ title || t("title") }} |
||||||
</template> |
</div> |
||||||
<el-menu-item v-for="child in menu.children" :index="getPath(child)" :router="router"> |
<template v-for="menu in data || state.menus"> |
||||||
<component class="icon" :width="getters.menuIconSize" :height="getters.menuIconSize" |
<template v-if="menu.children && menu.children.length > 0"> |
||||||
:is="child.icon || state.style.menuDefaultIcon"> |
<el-sub-menu :index="getPath(menu)" :key="menu.path"> |
||||||
</component> |
<template #title> |
||||||
{{ child.title || t(child.i18n) }} |
<component class="icon" :is="menu.icon || state.style.menuDefaultIcon"> </component> |
||||||
</el-menu-item> |
<span>{{ menu.title || t(menu.i18n) }}</span> |
||||||
</el-sub-menu> |
|
||||||
</template> |
|
||||||
<template v-else> |
|
||||||
<el-menu-item :index="getPath(menu)" :key="menu.path" :router="router"> |
|
||||||
<component class="icon" :is="menu.icon || state.style.menuDefaultIcon"></component> |
|
||||||
<span>{{ menu.title || t(menu.i18n) }}</span> |
|
||||||
</el-menu-item> |
|
||||||
</template> |
</template> |
||||||
|
<el-menu-item v-for="child in menu.children" :index="getPath(child)" :router="router"> |
||||||
|
<component |
||||||
|
class="icon" |
||||||
|
:width="getters.menuIconSize" |
||||||
|
:height="getters.menuIconSize" |
||||||
|
:is="child.icon || state.style.menuDefaultIcon" |
||||||
|
> |
||||||
|
</component> |
||||||
|
{{ child.title || t(child.i18n) }} |
||||||
|
</el-menu-item> |
||||||
|
</el-sub-menu> |
||||||
|
</template> |
||||||
|
<template v-else> |
||||||
|
<el-menu-item :index="getPath(menu)" :key="menu.path" :router="router"> |
||||||
|
<component class="icon" :is="menu.icon || state.style.menuDefaultIcon"></component> |
||||||
|
<span>{{ menu.title || t(menu.i18n) }}</span> |
||||||
|
</el-menu-item> |
||||||
</template> |
</template> |
||||||
|
</template> |
||||||
</el-menu> |
</el-menu> |
||||||
|
<div class="menu-footer"> |
||||||
|
<slot name="footer" /> |
||||||
|
</div> |
||||||
|
</div> |
||||||
</template> |
</template> |
||||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||||
import { useStore } from "vuex"; |
import { useStore } from "vuex"; |
||||||
import { useRouter } from "vue-router"; |
import { useRouter } from "vue-router"; |
||||||
import { ref, onMounted, reactive } from "vue" |
import { ref, onMounted, reactive } from "vue"; |
||||||
import { useI18n } from "vue3-i18n"; |
import { useI18n } from "vue3-i18n"; |
||||||
const { t } = useI18n(); |
const { t } = useI18n(); |
||||||
|
|
||||||
const { state, getters } = useStore() |
const { state, getters } = useStore(); |
||||||
const props = defineProps({ |
const props = defineProps({ |
||||||
mode: { |
mode: { |
||||||
type: String, |
type: String, |
||||||
default: 'vertical' |
default: "vertical", |
||||||
}, |
}, |
||||||
data: { |
data: { |
||||||
type: Array<any>(), |
type: Array<any>(), |
||||||
default: null |
default: null, |
||||||
}, |
}, |
||||||
logo: { |
logo: { |
||||||
type: String, |
type: String, |
||||||
default: null, |
default: null, |
||||||
}, |
}, |
||||||
title: { |
title: { |
||||||
type: String, |
type: String, |
||||||
default: null, |
default: null, |
||||||
}, |
}, |
||||||
}); |
}); |
||||||
|
|
||||||
const style = reactive({ 'margin-right': '10px', width: getters.menuIconSize, height: getters.menuIconSize }) |
const { VITE_APP_VERSION, VITE_GIT_HASH } = import.meta.env; |
||||||
|
const style = reactive({ "margin-right": "10px", width: getters.menuIconSize, height: getters.menuIconSize }); |
||||||
const router = useRouter(); |
const router = useRouter(); |
||||||
const getPath = (menu) => { |
const getPath = (menu) => { |
||||||
const prefix = menu.path.startsWith("/") ? "" : "/"; |
const prefix = menu.path.startsWith("/") ? "" : "/"; |
||||||
return prefix + menu.path; |
return prefix + menu.path; |
||||||
}; |
}; |
||||||
const active = ref(""); |
const active = ref(""); |
||||||
onMounted(() => { |
onMounted(() => { |
||||||
setTimeout(() => { |
setTimeout(() => { |
||||||
active.value = router.currentRoute.value.path.substring(1); |
active.value = router.currentRoute.value.path.substring(1); |
||||||
}, 200); |
}, 200); |
||||||
router.push(active.value); |
router.push(active.value); |
||||||
}) |
}); |
||||||
|
|
||||||
</script> |
</script> |
||||||
|
|
||||||
<style scoped lang="scss"> |
<style scoped lang="scss"> |
||||||
|
.menu-container { |
||||||
|
overflow: hidden; |
||||||
|
height: 100%; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
|
||||||
|
.el-menu { |
||||||
|
flex: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.menu-footer { |
||||||
|
background-color: v-bind("state.style.menuBg"); |
||||||
|
color: v-bind("state.style.menuColor"); |
||||||
|
font-size: 10px; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
.title { |
.title { |
||||||
height: v-bind('state.size.headHeight'); |
height: v-bind("state.size.headHeight"); |
||||||
width: v-bind('state.size.asideWidth'); |
width: v-bind("state.size.asideWidth"); |
||||||
text-align: center; |
text-align: center; |
||||||
font-size: v-bind('state.size.titleSize'); |
font-size: v-bind("state.size.titleSize"); |
||||||
line-height: v-bind('state.size.headHeight'); |
line-height: v-bind("state.size.headHeight"); |
||||||
font-weight: bold; |
font-weight: bold; |
||||||
color: v-bind('state.style.menuColor'); |
color: v-bind("state.style.menuColor"); |
||||||
} |
} |
||||||
|
|
||||||
.horizontal { |
.horizontal { |
||||||
padding-top: 1px; |
padding-top: 1px; |
||||||
height: v-bind('state.size.headHeight'); |
height: v-bind("state.size.headHeight"); |
||||||
border: none; |
border: none; |
||||||
// display: inline-flex; |
// display: inline-flex; |
||||||
} |
} |
||||||
|
|
||||||
.vertical { |
.vertical { |
||||||
padding-top: 1px; |
padding-top: 1px; |
||||||
// height: v-bind('state.size.mainHeight'); |
// height: v-bind('state.size.mainHeight'); |
||||||
height: 100%; |
height: 100%; |
||||||
border: none; |
border: none; |
||||||
} |
} |
||||||
|
|
||||||
.icon { |
.icon { |
||||||
margin-right: 10px; |
margin-right: 10px; |
||||||
width: v-bind('state.size.menuIconSize'); |
width: v-bind("state.size.menuIconSize"); |
||||||
height: v-bind('state.size.menuIconSize'); |
height: v-bind("state.size.menuIconSize"); |
||||||
} |
} |
||||||
|
|
||||||
.el-menu-item.is-active { |
.el-menu-item.is-active { |
||||||
background-color: v-bind('state.style.menuActiveBg'); |
background-color: v-bind("state.style.menuActiveBg"); |
||||||
} |
} |
||||||
|
|
||||||
.vertical .el-sub-menu, |
.vertical .el-sub-menu, |
||||||
.vertical .el-menu-item { |
.vertical .el-menu-item { |
||||||
min-width: v-bind('state.size.asideWidth') !important; |
min-width: v-bind("state.size.asideWidth") !important; |
||||||
font-size: v-bind('state.size.fontSize') !important; |
font-size: v-bind("state.size.fontSize") !important; |
||||||
} |
} |
||||||
|
|
||||||
.horizontal .el-sub-menu, |
.horizontal .el-sub-menu, |
||||||
.horizontal .el-menu-item { |
.horizontal .el-menu-item { |
||||||
font-size: v-bind('state.size.fontSize') !important; |
font-size: v-bind("state.size.fontSize") !important; |
||||||
} |
} |
||||||
</style> |
</style> |
||||||
|
|||||||
Loading…
Reference in new issue