<template>
<div class="sidebar">
<div>{{ t('menu.dashboard') }}</div>
<n-scrollbar>
<n-menu :options="menuOptions" />
</n-scrollbar>
</div>
</template>
<script lang="ts" setup>
import { h, Component, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { RouteRecordRaw, RouterLink } from 'vue-router'
import { useRouter } from 'vue-router'
import { computed } from 'vue'
import { useAppStore } from '@/store'
import type { MenuOption } from 'naive-ui'
import { NIcon } from 'naive-ui'
import { DashboardOutlined as DashboardIcon } from '@vicons/antd'
const router = useRouter()
const { t, locale } = useI18n()
console.log(router.getRoutes())
const appStore = useAppStore()
const routers = computed(() => {
return appStore.routers.filter(value => !value.meta?.hidden)
})
const menuOptions = ref<MenuOption[]>([])
const iconMap: { [index: string]: any } = {
Dashboard: DashboardIcon
}
function renderIcon(icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
const genMenu = () => {
menuOptions.value = []
for (const item of routers.value) {
const children = []
for (const item2 of item?.children || []) {
children.push({
label: () =>
h(
RouterLink,
{
to: {
name: item2.name
}
},
{ default: () => t(item2.meta?.locale as string) }
),
key: item2.name as string
})
}
const menu: MenuOption = {
key: item.name as string,
label: t(item.meta?.locale as string),
icon: renderIcon(iconMap[item.name as string]),
children
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
menuOptions.value.push(menu)
}
}
genMenu()
watch(
() => locale.value,
() => {
genMenu()
}
)
</script>
vue-router 的类型 RouteRecordRaw, 一个属性有好几种类型, 然后用起来 ts 总是报类型不匹配, 用了大量 as string 来解决报错, 好难受, 我之前都是写 js, 可能对 ts 理解有误, 怎么才能优雅的使用, 有个报错说我嵌套太深, 还不得不用 // @ts-ignore 来解决
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.