u
This commit is contained in:
1 parent
ff327ba2fd
commit
1217f7df5f
10 files changed
+503
-6
No files matched your search
@@ -1,12 +1,170 @@
|
||||
<script lang="ts" setup>
|
||||
import type { NavMenuItem } from '@/components/nav-menu/type'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import NavMenu from '@/components/nav-menu/index.vue'
|
||||
|
||||
const searchKey = ref('')
|
||||
const route = useRoute()
|
||||
|
||||
const menuRef = ref()
|
||||
|
||||
const menuList: NavMenuItem [] = [
|
||||
{
|
||||
label: '资料设置',
|
||||
index: '/settings/info',
|
||||
icon: 'hugeicons:setting-07',
|
||||
children: [
|
||||
{
|
||||
label: '公司信息设置',
|
||||
index: '/settings/info/company',
|
||||
icon: 'hugeicons:building-02',
|
||||
},
|
||||
{
|
||||
label: '成员设置',
|
||||
index: '/settings/info/company-user',
|
||||
icon: 'hugeicons:user-settings-01',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '创作者中心',
|
||||
index: '/settings/forum',
|
||||
icon: 'hugeicons:edit-01',
|
||||
children: [
|
||||
{
|
||||
label: '首页',
|
||||
index: '/settings/forum/home',
|
||||
icon: 'hugeicons:home-03',
|
||||
},
|
||||
{
|
||||
label: '写文章',
|
||||
index: '/settings/forum/editor',
|
||||
icon: 'hugeicons:edit-04',
|
||||
},
|
||||
{
|
||||
label: '帖子管理',
|
||||
index: '/settings/forum/post',
|
||||
icon: 'hugeicons:material-and-texture',
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
/**
|
||||
* 递归过滤菜单
|
||||
*/
|
||||
function filterMenu(
|
||||
list: NavMenuItem[],
|
||||
keyword: string,
|
||||
): NavMenuItem[] {
|
||||
if (!keyword)
|
||||
return list
|
||||
|
||||
return list
|
||||
.map((item) => {
|
||||
const hitSelf = item.label.includes(keyword)
|
||||
|
||||
// 递归检查子节点是否命中(但不裁剪 children)
|
||||
const hitChildren = item.children
|
||||
? filterMenu(item.children, keyword).length > 0
|
||||
: false
|
||||
|
||||
// 自己命中 或 任一子节点命中 → 保留整个节点
|
||||
if (hitSelf || hitChildren) {
|
||||
return item
|
||||
}
|
||||
|
||||
return null
|
||||
})
|
||||
.filter(Boolean) as NavMenuItem[]
|
||||
}
|
||||
|
||||
const filteredMenu = computed(() =>
|
||||
filterMenu(menuList, searchKey.value.trim()),
|
||||
)
|
||||
function collectOpeneds(menu: NavMenuItem[], result: string[] = []) {
|
||||
for (const item of menu) {
|
||||
if (item.children?.length) {
|
||||
result.push(item.index)
|
||||
collectOpeneds(item.children, result)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
watch(searchKey, async (val) => {
|
||||
await nextTick()
|
||||
|
||||
if (!menuRef.value)
|
||||
return
|
||||
|
||||
if (val) {
|
||||
const openeds = collectOpeneds(filteredMenu.value)
|
||||
openeds.forEach((index) => {
|
||||
menuRef.value!.open(index)
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="">
|
||||
settings
|
||||
<div class="settings-wrapper">
|
||||
<div class="left-menu">
|
||||
<el-input
|
||||
v-model="searchKey"
|
||||
placeholder="搜索菜单"
|
||||
size="large"
|
||||
:prefix-icon="Search"
|
||||
clearable
|
||||
/>
|
||||
|
||||
<el-menu
|
||||
ref="menuRef"
|
||||
router
|
||||
:default-active="route.path"
|
||||
>
|
||||
<NavMenu :menu="filteredMenu" />
|
||||
</el-menu>
|
||||
</div>
|
||||
|
||||
<div class="right-view">
|
||||
<router-view />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
//
|
||||
.settings-wrapper {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
margin-top: 30px;
|
||||
padding: 0px 240px;
|
||||
height: 800px;
|
||||
|
||||
.left-menu {
|
||||
font-size: 16px;
|
||||
overflow-y: auto;
|
||||
width: 240px;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
flex-shrink: 0;
|
||||
:deep(.el-input__wrapper) {
|
||||
margin: 12px 12px 4px 12px;
|
||||
}
|
||||
|
||||
:deep(.el-menu) {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
.right-view {
|
||||
width: 1200px;
|
||||
flex-shrink: 0;
|
||||
overflow-y: auto;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user