<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 来解决
