zs 1 year ago
parent
commit
0bd0bd6fd3

File diff suppressed because it is too large
+ 3765 - 47
package-lock.json


+ 2 - 1
package.json

@@ -35,6 +35,7 @@
     "unplugin-icons": "^0.18.5",
     "unplugin-vue-components": "^0.26.0",
     "vite": "^5.0.11",
-    "vite-plugin-inspect": "^0.8.3"
+    "vite-plugin-inspect": "^0.8.3",
+    "vite-plugin-svg-icons": "^2.0.1"
   }
 }

File diff suppressed because it is too large
+ 1 - 0
src/assets/icons/language.svg


+ 33 - 0
src/components/LangSelect/index.vue

@@ -0,0 +1,33 @@
+<script setup>
+// 组件
+import SvgIcon from '@/components/SvgIcon/index.vue'
+import { useI18n } from 'vue-i18n'
+import { useAppStore } from '@/store/modules/app'
+
+const appStore = useAppStore()
+const { locale } = useI18n()
+
+function handleLanguageChange(lang) {
+  locale.value = lang
+  appStore.changeLanguage(lang)
+  if (lang === 'en') {
+    ElMessage.success('Switch Language Successful!')
+  } else {
+    ElMessage.success('切换语言成功!')
+  }
+}
+</script>
+
+<template>
+  <el-dropdown trigger="click" @command="handleLanguageChange">
+    <div>
+      <component icon-class="language" :is="SvgIcon"></component>
+    </div>
+    <template #dropdown>
+      <el-dropdown-menu>
+        <el-dropdown-item :disabled="appStore.language === 'zh-cn'" command="zh-cn">中文</el-dropdown-item>
+        <el-dropdown-item :disabled="appStore.language === 'en'" command="en"> English</el-dropdown-item>
+      </el-dropdown-menu>
+    </template>
+  </el-dropdown>
+</template>

+ 43 - 0
src/components/SvgIcon/index.vue

@@ -0,0 +1,43 @@
+<template>
+  <svg aria-hidden="true" class="svg-icon" :style="'width:' + size + ';height:' + size">
+    <use :xlink:href="symbolId" :fill="color" />
+  </svg>
+</template>
+
+<script setup>
+const props = defineProps({
+  prefix: {
+    type: String,
+    default: 'icon'
+  },
+  iconClass: {
+    type: String,
+    required: false,
+    default: ''
+  },
+  color: {
+    type: String,
+    default: ''
+  },
+  size: {
+    type: String,
+    default: '1em'
+  }
+})
+
+const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`)
+</script>
+
+<style scoped>
+.svg-icon {
+  display: inline-block;
+  width: 1em;
+  height: 1em;
+  overflow: hidden;
+  vertical-align: -0.15em;
+  /* 因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果 */
+  outline: none;
+  fill: currentcolor;
+  /* 定义元素的颜色,currentColor是一个变量,这个变量的值就表示当前元素的color值,如果当前元素未设置color值,则从父元素继承 */
+}
+</style>

+ 21 - 5
src/layout/parts/Header.vue

@@ -6,13 +6,15 @@
           <component :is="breadcrumb"></component>
         </div>
         <div class="right">
+          <component class="navbar-item" :is="langSelect"></component>
           <el-dropdown>
-            <el-icon style="margin-right: 8px; margin-top: 1px"><setting /></el-icon>
+            <el-icon style="margin-right: 8px; margin-top: 1px">
+              <setting />
+            </el-icon>
             <template #dropdown>
               <el-dropdown-menu>
                 <el-dropdown-item>我的信息</el-dropdown-item>
-                <el-dropdown-item>其他</el-dropdown-item>
-                <el-dropdown-item @click="logout">退出登录</el-dropdown-item>
+                <el-dropdown-item @click="logout">注销</el-dropdown-item>
               </el-dropdown-menu>
             </template>
           </el-dropdown>
@@ -28,6 +30,7 @@
 <script setup>
 // 组件
 import breadcrumb from '@/components/Breadcrumb/index.vue'
+import langSelect from '@/components/LangSelect/index.vue'
 import { UserStore } from '@/store/user'
 const userStore = UserStore()
 const user = computed(() => userStore.user)
@@ -57,6 +60,19 @@ const logout = () => {
     display: inline-flex;
     align-items: center;
     justify-content: center;
+
+    .navbar-item {
+      display: inline-block;
+      width: 30px;
+      height: 50px;
+      line-height: 50px;
+      color: var(--el-text-color);
+      text-align: center;
+      cursor: pointer;
+
+      &:hover {
+        background: rgb(0 0 0 / 10%);
+      }
+    }
   }
-}
-</style>
+}</style>

+ 5 - 5
src/layout/parts/Sidebar.vue

@@ -22,7 +22,7 @@
                 <el-sub-menu :index="item._id" :key="item._id">
                   <template #title>
                     <i :class="['iconfont', item.icon]"></i>
-                    <span>{{ item.name }}</span>
+                    <span>{{ translateRouteTitle(item.name) }}</span>
                   </template>
                   <template v-for="subItem in item.children">
                     <!-- TODO:这里有问题需要改成自引用输出方式.实现无线嵌套.目前只是最多三级 -->
@@ -30,17 +30,17 @@
                       <el-sub-menu v-if="subItem.children && subItem.children.length > 0" :index="subItem._id" :key="subItem._id">
                         <template #title>
                           <i :class="['iconfont', subItem.icon]"></i>
-                          <span>{{ subItem.name }}</span>
+                          <span>{{ translateRouteTitle(subItem.name) }}</span>
                         </template>
                         <el-menu-item v-for="(threeItem, i) in subItem.children" :key="i" :index="threeItem.path">
                           <i :class="['iconfont', threeItem.icon]"></i>
-                          <span>{{ threeItem.name }}</span>
+                          <span>{{ translateRouteTitle(threeItem.name) }}</span>
                         </el-menu-item>
                       </el-sub-menu>
                     </template>
                     <el-menu-item v-else-if="subItem.type === '1'" :index="subItem.path" :key="subItem.path">
                       <i :class="['iconfont', subItem.icon]"></i>
-                      <span>{{ subItem.name }}</span>
+                      <span>{{ translateRouteTitle(subItem.name) }}</span>
                     </el-menu-item>
                   </template>
                 </el-sub-menu>
@@ -63,7 +63,7 @@
 import { siteInfo, menuInfo } from '@/layout/site'
 import { UserStore } from '@/store/user'
 import { useRoute } from 'vue-router'
-
+import { translateRouteTitle } from '@/utils/i18n'
 const route = useRoute()
 
 const onRoutes = ref(route.path)

+ 2 - 0
src/main.js

@@ -7,6 +7,8 @@ import router from './router'
 
 import * as ElementPlusIconsVue from '@element-plus/icons-vue'
 
+// 本地SVG图标
+import 'virtual:svg-icons-register'
 // 国际化
 
 const app = createApp(App)

+ 7 - 0
vite.config.js

@@ -3,6 +3,7 @@ import Components from 'unplugin-vue-components/vite'
 import Icons from 'unplugin-icons/vite'
 import IconsResolver from 'unplugin-icons/resolver'
 import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
+import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
 import { defineConfig, loadEnv } from 'vite'
 import vue from '@vitejs/plugin-vue'
 import Inspect from 'vite-plugin-inspect'
@@ -80,6 +81,12 @@ export default defineConfig(({ mode }) => {
       Icons({
         autoInstall: true
       }),
+      createSvgIconsPlugin({
+        // 指定需要缓存的图标文件夹
+        iconDirs: [path.resolve(pathSrc, 'assets/icons')],
+        // 指定symbolId格式
+        symbolId: 'icon-[dir]-[name]'
+      }),
       Inspect()
     ],
     // 预加载项目必需的组件