Browse Source

style(Icon): delete default color

wip(router): async import route developing
kailong321200875 3 years ago
parent
commit
95a2bd884d

+ 1 - 1
mock/user/index.ts

@@ -3,7 +3,7 @@ import { MockMethod } from 'vite-plugin-mock'
 
 const { result_code } = config
 
-const timeout = 2000
+const timeout = 1000
 
 const List: {
   username: string

+ 1 - 1
src/components/Icon/src/Icon.vue

@@ -13,7 +13,7 @@ const props = defineProps({
   // icon name
   icon: propTypes.string,
   // icon color
-  color: propTypes.string.def('#888'),
+  color: propTypes.string,
   // icon size
   size: propTypes.number.def(16)
 })

+ 3 - 1
src/locales/en.ts

@@ -23,7 +23,9 @@ export default {
     forgetPassword: 'Forget password'
   },
   router: {
-    login: 'Login'
+    login: 'Login',
+    level: 'Multi level menu',
+    menu: 'Menu'
   },
   mock: {
     loginErr: 'Wrong account or password'

+ 3 - 1
src/locales/zh-CN.ts

@@ -23,7 +23,9 @@ export default {
     forgetPassword: '忘记密码'
   },
   router: {
-    login: '登录'
+    login: '登录',
+    level: '多级菜单',
+    menu: '菜单'
   },
   mock: {
     loginErr: '账号或密码错误'

+ 27 - 0
src/router/helper.ts

@@ -0,0 +1,27 @@
+import ParentLayout from '@/components/ParentView/index.vue'
+import type { RouteLocationNormalized, RouteRecordNormalized } from 'vue-router'
+
+export const getParentLayout = (name: string) => {
+  return () =>
+    new Promise((resolve) => {
+      resolve({
+        ...ParentLayout,
+        name
+      })
+    })
+}
+
+export function getRoute(route: RouteLocationNormalized): RouteLocationNormalized {
+  if (!route) return route
+  const { matched, ...opt } = route
+  return {
+    ...opt,
+    matched: (matched
+      ? matched.map((item) => ({
+          meta: item.meta,
+          name: item.name,
+          path: item.path
+        }))
+      : undefined) as RouteRecordNormalized[]
+  }
+}

+ 61 - 0
src/router/index.ts

@@ -37,6 +37,67 @@ export const constantRouterMap: AppRouteRecordRaw[] = [
   }
 ]
 
+// export const asyncRouterMap: AppRouteRecordRaw[] = [
+//   {
+//     path: '/level',
+//     component: Layout,
+//     redirect: '/level/menu1/menu1-1/menu1-1-1',
+//     name: 'Level',
+//     meta: {
+//       title: t('router.level')
+//     },
+//     children: [
+//       {
+//         path: 'menu1',
+//         name: 'Menu1',
+//         component: getParentLayout('Menu1'),
+//         redirect: '/level/menu1/menu1-1/menu1-1-1',
+//         meta: {
+//           title: `${t('router.menu')}1`
+//         },
+//         children: [
+//           {
+//             path: 'menu1-1',
+//             name: 'Menu11',
+//             component: getParentLayout('Menu11Demo'),
+//             redirect: '/level/menu1/menu1-1/menu1-1-1',
+//             meta: {
+//               title: `${t('router.menu')}1-1`,
+//               alwaysShow: true
+//             },
+//             children: [
+//               {
+//                 path: 'menu1-1-1',
+//                 name: 'Menu111',
+//                 component: () => import('@/views/Level/Menu111.vue'),
+//                 meta: {
+//                   title: `${t('router.menu')}1-1-1`
+//                 }
+//               }
+//             ]
+//           },
+//           {
+//             path: 'menu1-2',
+//             name: 'Menu12',
+//             component: () => import('@/views/Level/Menu12.vue'),
+//             meta: {
+//               title: `${t('router.menu')}1-2`
+//             }
+//           }
+//         ]
+//       },
+//       {
+//         path: 'menu2',
+//         name: 'Menu2Demo',
+//         component: () => import('@/views/Level/Menu2.vue'),
+//         meta: {
+//           title: `${t('router.menu')}2`
+//         }
+//       }
+//     ]
+//   }
+// ]
+
 const router = createRouter({
   history: createWebHashHistory(),
   strict: true,

+ 180 - 0
src/store/modules/permission.ts

@@ -0,0 +1,180 @@
+// import { defineStore } from 'pinia'
+// import { asyncRouterMap, constantRouterMap } from '@/router'
+// import { useCache } from '@/hooks/web/useCache'
+// import { getParentLayout } from '@/router/helper'
+// import { store } from '../index'
+// import { useAppStoreWithOut } from '@/store/modules/app'
+// import { isUrl } from '@/utils/is'
+// import { deepClone } from '@/utils'
+
+// const { wsCache } = useCache()
+
+// const appStore = useAppStoreWithOut()
+
+// const modules = import.meta.glob('../../views/**/*.{vue,tsx}')
+
+// /* Layout */
+// const Layout = () => import('@/layout/index.vue')
+
+// export interface PermissionState {
+//   routers: AppRouteRecordRaw[]
+//   addRouters: AppRouteRecordRaw[]
+//   isAddRouters: boolean
+//   activeTab: string
+//   menuTabRouters: AppRouteRecordRaw[]
+// }
+
+// export const usePermissionStore = defineStore({
+//   id: 'permission',
+//   state: (): PermissionState => ({
+//     routers: [],
+//     addRouters: [],
+//     isAddRouters: false,
+//     menuTabRouters: [],
+//     activeTab: ''
+//   }),
+//   getters: {
+//     getRouters(): AppRouteRecordRaw[] {
+//       return this.routers
+//     },
+//     getAddRouters(): AppRouteRecordRaw[] {
+//       return this.addRouters
+//     },
+//     getIsAddRouters(): boolean {
+//       return this.isAddRouters
+//     },
+//     getActiveTab(): string {
+//       return this.activeTab
+//     },
+//     getMenuTabRouters(): AppRouteRecordRaw[] {
+//       return this.menuTabRouters
+//     }
+//   },
+//   actions: {
+//     generateRoutes(): Promise<unknown> {
+//       return new Promise<void>((resolve) => {
+//         // 路由权限控制
+//         let routerMap: AppRouteRecordRaw[] = []
+//         if (wsCache.get(appStore.getUserInfo).roleName === 'admin') {
+//           // 模拟前端控制权限
+//           routerMap = generateRoutesFn(deepClone(asyncRouterMap, ['component']))
+//         } else {
+//           // 模拟后端控制权限
+//           routerMap = getFilterRoutes(wsCache.get(appStore.getUserInfo).checkedNodes)
+//         }
+//         // const routerMap: AppRouteRecordRaw[] = generateRoutesFn(deepClone(asyncRouterMap, ['component']))
+//         // 动态路由,404一定要放到最后面
+//         this.addRouters = routerMap.concat([
+//           {
+//             path: '/:path(.*)*',
+//             redirect: '/404',
+//             name: '404',
+//             meta: {
+//               hidden: true,
+//               breadcrumb: false
+//             }
+//           }
+//         ])
+//         // 渲染菜单的所有路由
+//         this.routers = deepClone(constantRouterMap, ['component']).concat(routerMap)
+//         resolve()
+//       })
+//     },
+//     setIsAddRouters(state: boolean): void {
+//       this.isAddRouters = state
+//     },
+//     setMenuTabRouters(routers: AppRouteRecordRaw[]): void {
+//       this.menuTabRouters = routers
+//     },
+//     setAcitveTab(activeTab: string): void {
+//       this.activeTab = activeTab
+//     }
+//   }
+// })
+
+// // 路由过滤,主要用于权限控制
+// function generateRoutesFn(routes: AppRouteRecordRaw[], basePath = '/'): AppRouteRecordRaw[] {
+//   const res: AppRouteRecordRaw[] = []
+
+//   for (const route of routes) {
+//     // skip some route
+//     if (route.meta && route.meta.hidden && !route.meta.showMainRoute) {
+//       continue
+//     }
+
+//     let onlyOneChild: Nullable<string> = null
+
+//     if (route.children && route.children.length === 1 && !route.meta.alwaysShow) {
+//       onlyOneChild = (
+//         isUrl(route.children[0].path)
+//           ? route.children[0].path
+//           : path.resolve(path.resolve(basePath, route.path), route.children[0].path)
+//       ) as string
+//     }
+
+//     let data: Nullable<AppRouteRecordRaw> = null
+
+//     // 如不需要路由权限,可注释以下逻辑
+//     // 权限过滤,通过获取登录信息里面的角色权限,动态的渲染菜单。
+//     const list = wsCache.get(appStore.getUserInfo).checkedNodes
+//     // 开发者可以根据实际情况进行扩展
+//     for (const item of list) {
+//       // 通过路径去匹配
+//       if (isUrl(item.path) && (onlyOneChild === item.path || route.path === item.path)) {
+//         data = Object.assign({}, route)
+//       } else {
+//         const routePath = path.resolve(basePath, onlyOneChild || route.path)
+//         if (routePath === item.path || (route.meta && route.meta.followRoute === item.path)) {
+//           data = Object.assign({}, route)
+//         }
+//       }
+//     }
+//     // 如不需要路由权限,解注释下面一行
+//     // data = Object.assign({}, route)
+
+//     // recursive child routes
+//     if (route.children && data) {
+//       data.children = generateRoutesFn(route.children, path.resolve(basePath, data.path))
+//     }
+//     if (data) {
+//       res.push(data as AppRouteRecordRaw)
+//     }
+//   }
+//   return res
+// }
+
+// // 模拟后端过滤路由
+// function getFilterRoutes(routes: AppRouteRecordRaw[]): AppRouteRecordRaw[] {
+//   const res: AppRouteRecordRaw[] = []
+
+//   for (const route of routes) {
+//     const data: AppRouteRecordRaw = {
+//       path: route.path,
+//       name: route.name,
+//       redirect: route.redirect,
+//       meta: {}
+//     }
+//     data.meta = Object.assign({}, route.meta || {}, { title: route.meta.title })
+//     if (route.component) {
+//       // 动态加载路由文件,可根据实际情况进行自定义逻辑
+//       const component = route.component as string
+//       data.component = (
+//         component === '#'
+//           ? Layout
+//           : component.includes('##')
+//           ? getParentLayout(component.split('##')[1])
+//           : modules[`../../${route.component}.vue`] || modules[`../../${route.component}.tsx`]
+//       )
+//     }
+//     // recursive child routes
+//     if (route.children) {
+//       data.children = getFilterRoutes(route.children)
+//     }
+//     res.push(data as AppRouteRecordRaw)
+//   }
+//   return res
+// }
+
+// export function usePermissionStoreWithOut() {
+//   return usePermissionStore(store)
+// }

+ 20 - 0
src/utils/index.ts

@@ -34,3 +34,23 @@ export function underlineToHump(str: string): string {
     return letter.toUpperCase()
   })
 }
+
+/**
+ * 对象数组深拷贝
+ * @param {Array,Object} source 需要深拷贝的对象数组
+ * @param {Array} noClone 不需要深拷贝的属性集合
+ */
+export function deepClone(source: any, noClone: string[] = []): any {
+  if (!source && typeof source !== 'object') {
+    throw new Error('error arguments deepClone')
+  }
+  const targetObj: any = source.constructor === Array ? [] : {}
+  Object.keys(source).forEach((keys: string) => {
+    if (source[keys] && typeof source[keys] === 'object' && noClone.indexOf(keys) === -1) {
+      targetObj[keys] = deepClone(source[keys], noClone)
+    } else {
+      targetObj[keys] = source[keys]
+    }
+  })
+  return targetObj
+}

+ 5 - 0
src/views/Level/Menu111.vue

@@ -0,0 +1,5 @@
+<script setup lang="ts"></script>
+
+<template>
+  <div>Menu11</div>
+</template>

+ 5 - 0
src/views/Level/Menu12.vue

@@ -0,0 +1,5 @@
+<script setup lang="ts"></script>
+
+<template>
+  <div>Menu12</div>
+</template>

+ 5 - 0
src/views/Level/Menu2.vue

@@ -0,0 +1,5 @@
+<script setup lang="ts"></script>
+
+<template>
+  <div>Menu2</div>
+</template>