vue3+ts 根据路由来写生成侧边栏菜单, 总感觉 ts 用起来太别扭, 教教我正确用法 - V2EX
xpyusrs

vue3+ts 根据路由来写生成侧边栏菜单, 总感觉 ts 用起来太别扭, 教教我正确用法

  •  
  •   xpyusrs Dec 16, 2022 3099 views
    This topic created in 1245 days ago, the information mentioned may be changed or developed.
    <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 来解决

    13 replies    2022-12-16 20:25:54 +08:00
    gogogo2000
        1
    gogogo2000  
       Dec 16, 2022
    vue 对 ts 的兼容性一向来都不太好,这也是 react 的重大优势之一,有时候没办法只能 as any……
    shakaraka
        2
    shakaraka  
    PRO
       Dec 16, 2022
    你 routers 的类型推断出来了吗?还是什么问题单单代码看不出,你去 stackblitz.com 写个例子。
    xpyusrs
        3
    xpyusrs  
    OP
       Dec 16, 2022
    @gogogo2000 用 react 就没有这个问题了嘛? 如果这样的话我可以转 react
    anguiao
        5
    anguiao  
       Dec 16, 2022
    路由的元信息是可以预先声明的呀,文档里面有写。
    https://router.vuejs.org/zh/guide/advanced/meta.html#typescript
    chengxy
        6
    chengxy  
       Dec 16, 2022
    你用法不对,你的 routers 类型应该和 MenuOption 类型对上的,RouteRecordRaw 里面的参数你可以使用重写功能去重写。
    chengxy
        7
    chengxy  
       Dec 16, 2022
    @gogogo2000 #1 都 24 年了,现在完全不是问题了
    xpyusrs
        8
    xpyusrs  
    OP
       Dec 16, 2022
    @chengxy 重写能给个示例么, 我好模仿一下
    chengxy
        9
    chengxy  
       Dec 16, 2022
    @xpyusrs #8 5 楼给了
    ZoeeoZ
        10
    ZoeeoZ  
       Dec 16, 2022
    @xpyusrs ts 官方为 react 做了兼容..你说呢,所以 react+ts 才好用
    ccyu220
        11
    ccyu220  
       Dec 16, 2022
    我建议 menu 这种,你直接换成 tsx 来写。
    shakaraka
        12
    shakaraka  
    PRO
       Dec 16, 2022
    @xpyusrs #4

    噢噢。router meta 这个问题在 vue2 时代也是这样,只能类型覆盖。

    虽然但是,不建议直接把路由当做 navmenu 以及把路由表引到 ui 层使用,路由归路由,menu 归 menu 。这是个很标准的错误用法,虽然可以这么用,但是建议不。
    Bingchunmoli
        13
    Bingchunmoli  
       Dec 16, 2022 via Android
    没有 vue3 的一些代码示例,,pinia 什么的 ts 都不太会用
    About     Help     Advertise     Blog     API     FAQ     Solana     3310 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 48ms UTC 13:45 PVG 21:45 LAX 06:45 JFK 09:45
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86