Quellcode durchsuchen

feat: 全局图表组件注册

wanggaokun vor 1 Jahr
Ursprung
Commit
83b9c46723

+ 1 - 2
build/plugins.ts

@@ -6,7 +6,6 @@ import vueJsx from '@vitejs/plugin-vue-jsx'
 import eslintPlugin from 'vite-plugin-eslint'
 import simpleHtmlPlugin from 'vite-plugin-simple-html'
 import vueSetupExtend from 'unplugin-vue-setup-extend-plus/vite'
-import path from 'path'
 import createAutoImport from '../vite/plugins/auto-import'
 import createComponents from '../vite/plugins/components'
 import prismjsPlugin from '../vite/plugins/prismjs-plugin'
@@ -31,7 +30,7 @@ export const createVitePlugins = (viteEnv: ViteEnv, isBuild = false): (PluginOpt
     createAutoImport(),
     createComponents(),
     createIcons(),
-    createSvgIconsPlugin(path, isBuild),
+    createSvgIconsPlugin(isBuild),
     // 创建打包压缩配置
     createCompression(viteEnv),
     // 注入变量到 html 文件

+ 0 - 1
build/proxy.ts

@@ -16,7 +16,6 @@ export function createProxy(list: ProxyList = []) {
     const httpsRE = /^https:\/\//
     const isHttps = httpsRE.test(target)
     console.log('list', list)
-
     // https://github.com/http-party/node-http-proxy#options
     ret[prefix] = {
       target: target,

+ 3 - 3
src/api/interface/login.ts

@@ -15,9 +15,9 @@ export type RegisterForm = {
  * 登录请求
  */
 export interface LoginData {
-  tenantId?: number
-  username?: string
-  password?: string
+  tenantId?: number | string
+  username: string
+  password: string
   rememberMe?: boolean
   socialCode?: string
   socialState?: string

+ 2 - 2
src/components/SelectIcon/customIcons.ts

@@ -1,8 +1,8 @@
 // 导入自定义icon
 const myIcons: { [key: string]: any } = {}
-const modules = import.meta.glob('@/assets/icons/*.svg')
+const modules = import.meta.glob('@/assets/icons/svg/*.svg')
 for (const path in modules) {
-  const p = path.split('/src/assets/icons/')[1].split('.svg')[0]
+  const p = path.split('/src/assets/icons/svg/')[1].split('.svg')[0]
   myIcons[`${p}`] = { name: `${p}` }
 }
 export default myIcons

+ 14 - 3
src/components/SelectIcon/index.vue

@@ -10,7 +10,9 @@
       @click="openDialog"
     >
       <template #append>
-        <el-button :icon="customIcons[iconValue] || ''" />
+        <el-button>
+          <svg-icon v-if="iconValue" :name="iconValue" />
+        </el-button>
       </template>
     </el-input>
     <el-dialog v-model="dialogVisible" :title="placeholder" top="10%" width="40%">
@@ -18,7 +20,11 @@
       <el-scrollbar v-if="Object.keys(iconsList).length">
         <div class="icon-list">
           <div v-for="item in iconsList" :key="item" class="icon-item" @click="selectIcon(item)">
-            <component :is="item"></component>
+            <svg-icon v-if="item.name" :name="item.name" />
+            <span>{{ item.name }}</span>
+          </div>
+          <div v-for="item in myIcons" :key="item" class="icon-item" @click="selectIcon(item)">
+            <svg-icon v-if="item.name" :name="item.name" />
             <span>{{ item.name }}</span>
           </div>
         </div>
@@ -30,7 +36,7 @@
 
 <script setup lang="ts" name="SelectIcon">
 import * as Icons from '@element-plus/icons-vue'
-
+import myIcons from './customIcons'
 interface SelectIconProps {
   iconValue: string
   title?: string
@@ -80,6 +86,11 @@ const iconsList = computed((): { [key: string]: any } => {
   for (const key in customIcons) {
     if (key.toLowerCase().indexOf(inputValue.value.toLowerCase()) > -1) result[key] = customIcons[key]
   }
+  if (Object.keys(result).length == 0) {
+    for (const item in myIcons) {
+      if (item.toLowerCase().indexOf(inputValue.value.toLowerCase()) > -1) result[item] = { name: item }
+    }
+  }
   return result
 })
 </script>

+ 27 - 2
src/components/SvgIcon/index.vue

@@ -2,7 +2,7 @@
   <el-icon v-if="elIcons[props.name]">
     <component :style="iconStyle" :is="props.name"></component>
   </el-icon>
-  <svg v-else :style="iconStyle" aria-hidden="true">
+  <svg v-else :class="svgClass" :style="iconStyle" aria-hidden="true">
     <use :xlink:href="symbolId" :fill="color" />
   </svg>
 </template>
@@ -16,12 +16,37 @@ interface SvgProps {
   prefix?: string // 图标的前缀 ==> 非必传(默认为"icon")
   iconStyle?: CSSProperties // 图标的样式 ==> 非必传
   color?: string // 图标的样式填充颜色 ==> 非必传
+  className?: string // 图标的class ==> 非必传
 }
 
 const props = withDefaults(defineProps<SvgProps>(), {
   prefix: 'icon',
-  iconStyle: () => ({ width: '18px', height: '18px' })
+  iconStyle: () => ({})
 })
 
 const symbolId = computed(() => `#${props.prefix}-${props.name}`)
+const svgClass = computed(() => {
+  if (props.className) {
+    return `svg-icon ${props.className}`
+  }
+  return 'svg-icon'
+})
 </script>
+
+<style scope lang="scss">
+.sub-el-icon,
+.nav-icon {
+  position: relative;
+  display: inline-block;
+  margin-right: 12px;
+  font-size: 15px;
+}
+.svg-icon {
+  position: relative;
+  width: 1em;
+  height: 1em;
+  margin-right: 5px;
+  color: var(--color);
+  fill: currentColor;
+}
+</style>

+ 1 - 3
src/layouts/LayoutColumns/index.vue

@@ -14,9 +14,7 @@
             :class="{ 'split-active': splitActive === item.path || `/${splitActive.split('/')[1]}` === item.path }"
             @click="changeSubMenu(item)"
           >
-            <el-icon v-if="item.meta.icon">
-              <component :is="item.meta.icon"></component>
-            </el-icon>
+            <svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
             <span class="title">{{ item.meta.title }}</span>
           </div>
         </div>

+ 2 - 6
src/layouts/LayoutTransverse/index.vue

@@ -11,17 +11,13 @@
         <template v-for="subItem in menuList" :key="subItem.path">
           <el-sub-menu v-if="subItem.children?.length" :key="subItem.path" :index="subItem.path + 'el-sub-menu'">
             <template #title>
-              <el-icon v-if="subItem.meta.icon">
-                <component :is="subItem.meta.icon"></component>
-              </el-icon>
+              <svg-icon v-if="subItem.meta.icon" :name="subItem.meta.icon" />
               <span>{{ subItem.meta.title }}</span>
             </template>
             <SubMenu :menu-list="subItem.children" />
           </el-sub-menu>
           <el-menu-item v-else :key="subItem.path + 'el-menu-item'" :index="subItem.path" @click="handleClickMenu(subItem)">
-            <el-icon v-if="subItem.meta.icon">
-              <component :is="subItem.meta.icon"></component>
-            </el-icon>
+            <svg-icon v-if="subItem.meta.icon" :name="subItem.meta.icon" />
             <template #title>
               <span>{{ subItem.meta.title }}</span>
             </template>

+ 2 - 4
src/layouts/components/Header/components/Breadcrumb.vue

@@ -4,9 +4,7 @@
       <transition-group name="breadcrumb">
         <el-breadcrumb-item v-for="(item, index) in breadcrumbList" :key="item.path">
           <div class="el-breadcrumb__inner is-link" :class="{ 'item-no-icon': !item.meta.icon }" @click="onBreadcrumbClick(item, index)">
-            <!-- <el-icon v-if="item.meta.icon && globalStore.breadcrumbIcon" class="breadcrumb-icon">
-              <component :is="item.meta.icon"></component>
-            </el-icon> -->
+            <svg-icon v-if="item.meta.icon && globalStore.breadcrumbIcon" :name="item.meta.icon" class="breadcrumb-icon" />
             <span class="breadcrumb-title">{{ item.meta.title }}</span>
           </div>
         </el-breadcrumb-item>
@@ -69,7 +67,7 @@ const onBreadcrumbClick = (item: Menu.MenuOptions, index: number) => {
           font-size: 16px;
         }
         .breadcrumb-title {
-          margin-top: 2px;
+          margin-top: 1px;
         }
       }
       &:last-child .el-breadcrumb__inner,

+ 5 - 6
src/layouts/components/Menu/SubMenu.vue

@@ -2,17 +2,13 @@
   <template v-for="subItem in menuList" :key="subItem.path">
     <el-sub-menu v-if="subItem.children?.length" :index="subItem.path">
       <template #title>
-        <el-icon v-if="subItem.meta.icon">
-          <component :is="subItem.meta.icon"></component>
-        </el-icon>
+        <svg-icon v-if="subItem.meta.icon" :name="subItem.meta.icon" class="menu-svg-icon" />
         <span class="sle" :title="subItem.meta.title">{{ subItem.meta.title }}</span>
       </template>
       <SubMenu :menu-list="subItem.children" />
     </el-sub-menu>
     <el-menu-item v-else :index="subItem.path" @click="handleClickMenu(subItem)">
-      <el-icon v-if="subItem.meta.icon">
-        <component :is="subItem.meta.icon"></component>
-      </el-icon>
+      <svg-icon v-if="subItem.meta.icon" :name="subItem.meta.icon" class="menu-svg-icon" />
       <template #title>
         <span class="sle" :title="subItem.meta.title">{{ subItem.meta.title }}</span>
       </template>
@@ -31,6 +27,9 @@ const handleClickMenu = (subItem: Menu.MenuOptions) => {
 </script>
 
 <style lang="scss">
+.menu-svg-icon {
+  width: 24px;
+}
 .el-sub-menu .el-sub-menu__title:hover {
   color: var(--el-menu-hover-text-color) !important;
   background-color: var(--el-menu-active-bg-color) !important;

+ 5 - 5
src/layouts/components/Tabs/index.vue

@@ -4,9 +4,7 @@
       <el-tabs v-model="tabsMenuValue" type="card" @tab-click="tabClick" @tab-remove="tabRemove">
         <el-tab-pane v-for="item in tabsMenuList" :key="item.path" :label="item.title" :name="item.path" :closable="item.close">
           <template #label>
-            <el-icon v-if="item.icon && tabsIcon" class="tabs-icon">
-              <component :is="item.icon"></component>
-            </el-icon>
+            <svg-icon v-if="item.icon && tabsIcon" :name="item.icon" class="tabs-icon" />
             {{ item.title }}
           </template>
         </el-tab-pane>
@@ -31,7 +29,9 @@ const authStore = useAuthStore()
 const globalStore = useGlobalStore()
 
 const tabsMenuValue = ref(route.fullPath)
-const tabsMenuList = computed(() => tabStore.tabsMenuList)
+const tabsMenuList = computed(() => {
+  return tabStore.tabsMenuList
+})
 const tabsIcon = computed(() => globalStore.tabsIcon)
 
 onMounted(() => {
@@ -62,7 +62,7 @@ watch(
 const initTabs = () => {
   authStore.flatMenuListGet.forEach(item => {
     if (!item.meta) {
-      console.log('item', item)
+      return
     }
     if (item.meta.affix && !item.hidden && !item.meta.full) {
       const tabsParams = {

+ 3 - 3
src/layouts/components/ThemeDrawer/index.vue

@@ -108,10 +108,10 @@
       <span>面包屑</span>
       <el-switch v-model="breadcrumb" />
     </div>
-    <!-- <div class="theme-item">
+    <div class="theme-item">
       <span>面包屑图标</span>
       <el-switch v-model="breadcrumbIcon" />
-    </div> -->
+    </div>
     <div class="theme-item">
       <span>标签栏</span>
       <el-switch v-model="tabs" />
@@ -138,7 +138,7 @@ import SwitchDark from '@/components/SwitchDark/index.vue'
 const { changePrimary, changeGreyOrWeak, setAsideTheme, setHeaderTheme } = useTheme()
 
 const globalStore = useGlobalStore()
-const { layout, primary, isGrey, isWeak, asideInverted, headerInverted, isCollapse, accordion, breadcrumb, tabs, tabsIcon, footer } =
+const { layout, primary, isGrey, isWeak, breadcrumbIcon, asideInverted, headerInverted, isCollapse, accordion, breadcrumb, tabs, tabsIcon, footer } =
   storeToRefs(globalStore)
 
 // 预定义主题颜色

+ 1 - 1
src/routers/modules/routerData.json

@@ -7,7 +7,7 @@
       "component": "index",
       "hidden": false,
       "meta": {
-        "icon": "",
+        "icon": "HomeFilled",
         "title": "首页",
         "link": "",
         "full": false,

+ 2 - 2
src/views/login/components/LoginForm.vue

@@ -33,7 +33,7 @@
 <script setup lang="ts">
 import { HOME_URL } from '@/config'
 import { getTimeState } from '@/utils'
-import { Login } from '@/api/interface'
+import { LoginData } from '@/api/interface/login'
 import { ElNotification } from 'element-plus'
 import { getCodeImg } from '@/api/modules/login'
 import { useUserStore } from '@/stores/modules/user'
@@ -58,7 +58,7 @@ const loginRules = reactive({
 })
 const codeUrl = ref<string>('')
 const loading = ref(false)
-const loginForm = reactive<Login.ReqLoginForm>({
+const loginForm = reactive<LoginData>({
   username: 'superadmin',
   password: 'admin123',
   rememberMe: false,

+ 3 - 2
src/views/system/menu/index.vue

@@ -16,9 +16,10 @@
       </template>
       <!-- 菜单图标 -->
       <template #icon="scope">
-        <el-icon :size="18" v-if="scope.row.icon">
+        <!-- <el-icon :size="18" v-if="scope.row.icon">
           <component :is="scope.row.icon"></component>
-        </el-icon>
+        </el-icon> -->
+        <svg-icon v-if="scope.row.icon" :name="scope.row.icon" />
       </template>
       <!-- 表格操作 -->
       <template #operation="scope">

+ 3 - 2
vite/plugins/svg-icon.ts

@@ -1,8 +1,9 @@
 import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
-export default (path: any, isBuild: boolean) => {
+import { resolve } from 'path'
+export default (isBuild: boolean) => {
   return createSvgIconsPlugin({
     // 指定需要缓存的图标文件夹
-    iconDirs: [path.resolve(path.resolve(__dirname, '../../src'), 'assets/icons/svg')],
+    iconDirs: [resolve(process.cwd(), 'src/assets/icons/svg')],
     // 指定symbolId格式
     symbolId: 'icon-[dir]-[name]',
     svgoOptions: isBuild