index.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. import { createRouter, createWebHashHistory } from 'vue-router'
  2. import type { RouteRecordRaw } from 'vue-router'
  3. import { AppRouteRecordRaw } from './types'
  4. import type { App } from 'vue'
  5. import { getParentLayout } from './utils'
  6. /* Layout */
  7. const Layout = () => import('../layout/index.vue')
  8. /**
  9. * redirect: noredirect 当设置 noredirect 的时候该路由在面包屑导航中不可被点击
  10. * name:'router-name' 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
  11. * meta : {
  12. hidden: true 当设置 true 的时候该路由不会再侧边栏出现 如404,login等页面(默认 false)
  13. alwaysShow: true 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式,
  14. 只有一个时,会将那个子路由当做根路由显示在侧边栏,
  15. 若你想不管路由下面的 children 声明的个数都显示你的根路由,
  16. 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,
  17. 一直显示根路由(默认 false)
  18. title: 'title' 设置该路由在侧边栏和面包屑中展示的名字
  19. icon: 'svg-name' 设置该路由的图标
  20. noCache: true 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
  21. breadcrumb: false 如果设置为false,则不会在breadcrumb面包屑中显示(默认 true)
  22. affix: true 如果设置为true,则会一直固定在tag项中(默认 false)
  23. noTagsView: true 如果设置为true,则不会出现在tag中(默认 false)
  24. activeMenu: '/dashboard' 显示高亮的路由路径
  25. followAuth: '/dashboard' 跟随哪个路由进行权限过滤
  26. showMainRoute: true 设置为true即使hidden为true,也依然可以进行路由跳转(默认 false)
  27. followRoute: '/dashboard' 为路由设置跟随其他路由的权限
  28. }
  29. **/
  30. export const constantRouterMap: AppRouteRecordRaw[] = [
  31. {
  32. path: '/redirect',
  33. component: Layout,
  34. children: [
  35. {
  36. path: '/redirect/:path*',
  37. component: () => import('_c/Redirect/index.vue'),
  38. meta: {}
  39. }
  40. ],
  41. meta: {
  42. hidden: true
  43. }
  44. },
  45. {
  46. path: '/404',
  47. component: () => import('_c/Error/404.vue'),
  48. name: 'NoFind',
  49. meta: {
  50. hidden: true,
  51. title: '404',
  52. noTagsView: true
  53. }
  54. },
  55. {
  56. path: '/login',
  57. component: () => import('_p/index/views/login/index.vue'),
  58. name: 'Login',
  59. meta: {
  60. hidden: true,
  61. title: '登录',
  62. noTagsView: true
  63. }
  64. },
  65. {
  66. path: '/',
  67. component: Layout,
  68. redirect: '/dashboard',
  69. name: 'Root',
  70. meta: {},
  71. children: [
  72. {
  73. path: 'dashboard',
  74. component: () => import('_p/index/views/dashboard/index.vue'),
  75. name: 'Dashboard',
  76. meta: {
  77. title: '首页',
  78. icon: 'dashboard',
  79. noCache: true,
  80. affix: true
  81. }
  82. }
  83. ]
  84. },
  85. {
  86. path: '/external-link',
  87. component: Layout,
  88. meta: {},
  89. children: [
  90. {
  91. path: 'http://8.133.179.48:4000/dist-doc/',
  92. meta: { title: '文档', icon: 'documentation' }
  93. }
  94. ]
  95. }
  96. ]
  97. export const asyncRouterMap: AppRouteRecordRaw[] = [
  98. {
  99. path: '/components-demo',
  100. component: Layout,
  101. redirect: '/components-demo/echarts',
  102. name: 'ComponentsDemo',
  103. meta: {
  104. title: '功能组件',
  105. icon: 'component',
  106. alwaysShow: true
  107. },
  108. children: [
  109. {
  110. path: 'echarts',
  111. component: () => import('_p/index/views/components-demo/echarts/index.vue'),
  112. name: 'EchartsDemo',
  113. meta: {
  114. title: '图表'
  115. }
  116. },
  117. {
  118. path: 'preview',
  119. component: () => import('_p/index/views/components-demo/preview/index.vue'),
  120. name: 'PreviewDemo',
  121. meta: {
  122. title: '图片预览'
  123. }
  124. },
  125. {
  126. path: 'button',
  127. component: () => import('_p/index/views/components-demo/button/index.vue'),
  128. name: 'ButtonDemo',
  129. meta: {
  130. title: '按钮'
  131. }
  132. },
  133. {
  134. path: 'message',
  135. component: () => import('_p/index/views/components-demo/message/index.vue'),
  136. name: 'MessageDemo',
  137. meta: {
  138. title: '消息提示'
  139. }
  140. },
  141. {
  142. path: 'count-to',
  143. component: () => import('_p/index/views/components-demo/count-to/index.vue'),
  144. name: 'CountToDemo',
  145. meta: {
  146. title: '数字动画'
  147. }
  148. },
  149. {
  150. path: 'search',
  151. component: () => import('_p/index/views/components-demo/search/index.vue'),
  152. name: 'SearchDemo',
  153. meta: {
  154. title: '查询'
  155. }
  156. },
  157. {
  158. path: 'editor',
  159. component: () => import('_p/index/views/components-demo/editor/index.vue'),
  160. name: 'EditorDemo',
  161. meta: {
  162. title: '富文本编辑器'
  163. }
  164. },
  165. {
  166. path: 'markdown',
  167. component: () => import('_p/index/views/components-demo/markdown/index.vue'),
  168. name: 'MarkdownDemo',
  169. meta: {
  170. title: 'markdown编辑器'
  171. }
  172. },
  173. {
  174. path: 'dialog',
  175. component: () => import('_p/index/views/components-demo/dialog/index.vue'),
  176. name: 'DialogDemo',
  177. meta: {
  178. title: '弹窗'
  179. }
  180. },
  181. {
  182. path: 'more',
  183. component: () => import('_p/index/views/components-demo/more/index.vue'),
  184. name: 'MoreDemo',
  185. meta: {
  186. title: '显示更多'
  187. }
  188. },
  189. {
  190. path: 'detail',
  191. component: () => import('_p/index/views/components-demo/detail/index.vue'),
  192. name: 'DetailDemo',
  193. meta: {
  194. title: '详情组件'
  195. }
  196. },
  197. {
  198. path: 'qrcode',
  199. component: () => import('_p/index/views/components-demo/qrcode/index.vue'),
  200. name: 'QrcodeDemo',
  201. meta: {
  202. title: '二维码组件'
  203. }
  204. }
  205. ]
  206. },
  207. {
  208. path: '/table-demo',
  209. component: Layout,
  210. redirect: '/table-demo/basic-usage',
  211. name: 'TableDemo',
  212. meta: {
  213. title: '表格',
  214. icon: 'table',
  215. alwaysShow: true
  216. },
  217. children: [
  218. // {
  219. // path: 'test',
  220. // component: () => import('_p/index/views/table-demo/test'),
  221. // name: 'test',
  222. // meta: {
  223. // title: 'test'
  224. // }
  225. // },
  226. {
  227. path: 'basic-table',
  228. component: () => import('_p/index/views/table-demo/basic-table/index.vue'),
  229. name: 'BasicTable',
  230. meta: {
  231. title: '基础表格'
  232. }
  233. },
  234. {
  235. path: 'page-table',
  236. component: () => import('_p/index/views/table-demo/page-table/index.vue'),
  237. name: 'PageTable',
  238. meta: {
  239. title: '分页表格'
  240. }
  241. },
  242. {
  243. path: 'stripe-table',
  244. component: () => import('_p/index/views/table-demo/stripe-table/index.vue'),
  245. name: 'StripeTable',
  246. meta: {
  247. title: '带斑马纹表格'
  248. }
  249. },
  250. {
  251. path: 'border-table',
  252. component: () => import('_p/index/views/table-demo/border-table/index.vue'),
  253. name: 'BorderTable',
  254. meta: {
  255. title: '带边框表格'
  256. }
  257. },
  258. {
  259. path: 'state-table',
  260. component: () => import('_p/index/views/table-demo/state-table/index.vue'),
  261. name: 'StateTable',
  262. meta: {
  263. title: '带状态表格'
  264. }
  265. },
  266. {
  267. path: 'fixed-header',
  268. component: () => import('_p/index/views/table-demo/fixed-header/index.vue'),
  269. name: 'FixedHeader',
  270. meta: {
  271. title: '固定表头'
  272. }
  273. },
  274. {
  275. path: 'fixed-column',
  276. component: () => import('_p/index/views/table-demo/fixed-column/index.vue'),
  277. name: 'FixedColumn',
  278. meta: {
  279. title: '固定列'
  280. }
  281. },
  282. {
  283. path: 'fixed-column-header',
  284. component: () => import('_p/index/views/table-demo/fixed-column-header/index.vue'),
  285. name: 'FixedColumnHeader',
  286. meta: {
  287. title: '固定列和表头'
  288. }
  289. },
  290. {
  291. path: 'fluid-height',
  292. component: () => import('_p/index/views/table-demo/fluid-height/index.vue'),
  293. name: 'FluidHeight',
  294. meta: {
  295. title: '流体高度'
  296. }
  297. },
  298. {
  299. path: 'multi-header',
  300. component: () => import('_p/index/views/table-demo/multi-header/index.vue'),
  301. name: 'MultiHeader',
  302. meta: {
  303. title: '多级表头'
  304. }
  305. },
  306. {
  307. path: 'single-choice',
  308. component: () => import('_p/index/views/table-demo/single-choice/index.vue'),
  309. name: 'SingleChoice',
  310. meta: {
  311. title: '单选'
  312. }
  313. },
  314. {
  315. path: 'multiple-choice',
  316. component: () => import('_p/index/views/table-demo/multiple-choice/index.vue'),
  317. name: 'MultipleChoice',
  318. meta: {
  319. title: '多选'
  320. }
  321. },
  322. {
  323. path: 'sort-table',
  324. component: () => import('_p/index/views/table-demo/sort-table/index.vue'),
  325. name: 'SortTable',
  326. meta: {
  327. title: '排序'
  328. }
  329. },
  330. {
  331. path: 'screen-table',
  332. component: () => import('_p/index/views/table-demo/screen-table/index.vue'),
  333. name: 'ScreenTable',
  334. meta: {
  335. title: '筛选'
  336. }
  337. },
  338. {
  339. path: 'expand-row',
  340. component: () => import('_p/index/views/table-demo/expand-row/index.vue'),
  341. name: 'ExpandRow',
  342. meta: {
  343. title: '展开行'
  344. }
  345. },
  346. {
  347. path: 'tree-and-load',
  348. component: () => import('_p/index/views/table-demo/tree-and-load/index.vue'),
  349. name: 'TreeAndLoad',
  350. meta: {
  351. title: '树形数据与懒加载'
  352. }
  353. },
  354. {
  355. path: 'custom-header',
  356. component: () => import('_p/index/views/table-demo/custom-header/index.vue'),
  357. name: 'CustomHeader',
  358. meta: {
  359. title: '自定义表头'
  360. }
  361. },
  362. {
  363. path: 'total-table',
  364. component: () => import('_p/index/views/table-demo/total-table/index.vue'),
  365. name: 'TotalTable',
  366. meta: {
  367. title: '表尾合计行'
  368. }
  369. },
  370. {
  371. path: 'merge-table',
  372. component: () => import('_p/index/views/table-demo/merge-table/index.vue'),
  373. name: 'MergeTable',
  374. meta: {
  375. title: '合并行或列'
  376. }
  377. },
  378. {
  379. path: 'custom-index',
  380. component: () => import('_p/index/views/table-demo/custom-index/index.vue'),
  381. name: 'CustomIndex',
  382. meta: {
  383. title: '自定义索引'
  384. }
  385. }
  386. ]
  387. },
  388. {
  389. path: '/directives-demo',
  390. component: Layout,
  391. redirect: '/directives-demo/clipboard',
  392. name: 'DirectivesDemo',
  393. meta: {
  394. title: '自定义指令',
  395. icon: 'clipboard',
  396. alwaysShow: true
  397. },
  398. children: [
  399. {
  400. path: 'clipboard',
  401. component: () => import('_p/index/views/directives-demo/clipboard/index.vue'),
  402. name: 'ClipboardDemo',
  403. meta: {
  404. title: 'Clipboard'
  405. }
  406. }
  407. ]
  408. },
  409. {
  410. path: '/hooks-demo',
  411. component: Layout,
  412. redirect: '/hooks-demo/watermark',
  413. name: 'HooksDemo',
  414. meta: {
  415. title: 'Hooks',
  416. icon: 'international',
  417. alwaysShow: true
  418. },
  419. children: [
  420. {
  421. path: 'watermark',
  422. component: () => import('_p/index/views/hooks-demo/useWatermark/index.vue'),
  423. name: 'UseWatermarkDemo',
  424. meta: {
  425. title: 'UseWaterMark'
  426. }
  427. },
  428. {
  429. path: 'useScrollTo',
  430. component: () => import('_p/index/views/hooks-demo/useScrollTo/index.vue'),
  431. name: 'UseScrollToDemo',
  432. meta: {
  433. title: 'UseScrollTo'
  434. }
  435. }
  436. ]
  437. },
  438. {
  439. path: '/icon',
  440. component: Layout,
  441. name: 'IconsDemo',
  442. meta: {},
  443. children: [
  444. {
  445. path: 'index',
  446. component: () => import('_p/index/views/icons/index.vue'),
  447. name: 'Icons',
  448. meta: {
  449. title: '图标',
  450. icon: 'icon'
  451. }
  452. }
  453. ]
  454. },
  455. {
  456. path: '/level',
  457. component: Layout,
  458. redirect: '/level/menu1/menu1-1/menu1-1-1',
  459. name: 'Level',
  460. meta: {
  461. title: '多级菜单缓存',
  462. icon: 'nested'
  463. },
  464. children: [
  465. {
  466. path: 'menu1',
  467. name: 'Menu1Demo',
  468. component: getParentLayout('Menu1Demo'),
  469. redirect: '/level/menu1/menu1-1/menu1-1-1',
  470. meta: {
  471. title: 'Menu1'
  472. },
  473. children: [
  474. {
  475. path: 'menu1-1',
  476. name: 'Menu11Demo',
  477. component: getParentLayout('Menu11Demo'),
  478. redirect: '/level/menu1/menu1-1/menu1-1-1',
  479. meta: {
  480. title: 'Menu1-1',
  481. alwaysShow: true
  482. },
  483. children: [
  484. {
  485. path: 'menu1-1-1',
  486. name: 'Menu111Demo',
  487. component: () => import('_p/index/views/level/Menu111.vue'),
  488. meta: {
  489. title: 'Menu1-1-1'
  490. }
  491. }
  492. ]
  493. },
  494. {
  495. path: 'menu1-2',
  496. name: 'Menu12Demo',
  497. component: () => import('_p/index/views/level/Menu12.vue'),
  498. meta: {
  499. title: 'Menu1-2'
  500. }
  501. }
  502. ]
  503. },
  504. {
  505. path: 'menu2',
  506. name: 'Menu2Demo',
  507. component: () => import('_p/index/views/level/Menu2.vue'),
  508. meta: {
  509. title: 'Menu2'
  510. }
  511. }
  512. ]
  513. },
  514. {
  515. path: '/example-demo',
  516. component: Layout,
  517. name: 'ExampleDemo',
  518. redirect: '/example-demo/example-dialog',
  519. meta: {
  520. alwaysShow: true,
  521. icon: 'example',
  522. title: '综合实例'
  523. },
  524. children: [
  525. {
  526. path: 'example-dialog',
  527. component: () => import('_p/index/views/example-demo/example-dialog/index.vue'),
  528. name: 'ExampleDialog',
  529. meta: {
  530. title: '列表综合实例-弹窗'
  531. }
  532. },
  533. {
  534. path: 'example-page',
  535. component: () => import('_p/index/views/example-demo/example-page/index.vue'),
  536. name: 'ExamplePage',
  537. meta: {
  538. title: '列表综合实例-页面'
  539. }
  540. },
  541. {
  542. path: 'example-add',
  543. component: () => import('_p/index/views/example-demo/example-page/example-add.vue'),
  544. name: 'ExampleAdd',
  545. meta: {
  546. title: '列表综合实例-新增',
  547. noTagsView: true,
  548. noCache: true,
  549. hidden: true,
  550. showMainRoute: true,
  551. activeMenu: '/example-demo/example-page'
  552. }
  553. },
  554. {
  555. path: 'example-edit',
  556. component: () => import('_p/index/views/example-demo/example-page/example-edit.vue'),
  557. name: 'ExampleEdit',
  558. meta: {
  559. title: '列表综合实例-编辑',
  560. noTagsView: true,
  561. noCache: true,
  562. hidden: true,
  563. showMainRoute: true,
  564. activeMenu: '/example-demo/example-page'
  565. }
  566. },
  567. {
  568. path: 'example-detail',
  569. component: () => import('_p/index/views/example-demo/example-page/example-detail.vue'),
  570. name: 'ExampleDetail',
  571. meta: {
  572. title: '列表综合实例-详情',
  573. noTagsView: true,
  574. noCache: true,
  575. hidden: true,
  576. showMainRoute: true,
  577. activeMenu: '/example-demo/example-page'
  578. }
  579. }
  580. ]
  581. },
  582. {
  583. path: '/role-demo',
  584. component: Layout,
  585. redirect: '/role-demo/user',
  586. name: 'RoleDemo',
  587. meta: {
  588. title: '权限管理',
  589. icon: 'user',
  590. alwaysShow: true
  591. },
  592. children: [
  593. {
  594. path: 'user',
  595. component: () => import('_p/index/views/role-demo/user/index.vue'),
  596. name: 'User',
  597. meta: {
  598. title: '用户管理'
  599. }
  600. },
  601. {
  602. path: 'role',
  603. component: () => import('_p/index/views/role-demo/role/index.vue'),
  604. name: 'Role',
  605. meta: {
  606. title: '角色管理'
  607. }
  608. }
  609. ]
  610. }
  611. ]
  612. const router = createRouter({
  613. history: createWebHashHistory(),
  614. strict: true,
  615. routes: constantRouterMap as RouteRecordRaw[]
  616. })
  617. export function resetRouter(): void {
  618. const resetWhiteNameList = [
  619. 'RedirectRoot',
  620. 'Redirect',
  621. 'Login',
  622. 'Root',
  623. 'Dashboard',
  624. 'Page404'
  625. ]
  626. router.getRoutes().forEach((route) => {
  627. const { name } = route
  628. if (name && !resetWhiteNameList.includes(name as string)) {
  629. router.hasRoute(name) && router.removeRoute(name)
  630. }
  631. })
  632. }
  633. export function setupRouter(app: App<Element>) {
  634. app.use(router)
  635. }
  636. export default router