瀏覽代碼

feat(Component): Setting component add copy button

陈凯龙 3 年之前
父節點
當前提交
e496096539

+ 91 - 1
src/components/Setting/src/Setting.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { ElDrawer, ElDivider } from 'element-plus'
+import { ElDrawer, ElDivider, ElButton, ElMessage } from 'element-plus'
 import { ref, unref, computed, watch } from 'vue'
 import { useI18n } from '@/hooks/web/useI18n'
 import { ThemeSwitch } from '@/components/ThemeSwitch'
@@ -10,6 +10,8 @@ import { trim, setCssVar } from '@/utils'
 import ColorRadioPicker from './components/ColorRadioPicker.vue'
 import InterfaceDisplay from './components/InterfaceDisplay.vue'
 import LayoutRadioPicker from './components/LayoutRadioPicker.vue'
+import { useCache } from '@/hooks/web/useCache'
+import { useClipboard } from '@vueuse/core'
 
 const appStore = useAppStore()
 
@@ -100,6 +102,84 @@ watch(
     }
   }
 )
+
+// 拷贝
+const copyConfig = async () => {
+  const { copy, copied } = useClipboard({
+    source: `
+// 面包屑
+breadcrumb: ${appStore.getBreadcrumb},
+// 面包屑图标
+breadcrumbIcon: ${appStore.getBreadcrumbIcon},
+// 折叠图标
+hamburger: ${appStore.getHamburger},
+// 全屏图标
+screenfull: ${appStore.getScreenfull},
+// 尺寸图标
+size: ${appStore.getSize},
+// 多语言图标
+locale: ${appStore.getLocale},
+// 标签页
+tagsView: ${appStore.getTagsView},
+// logo
+logo: ${appStore.getLogo},
+// 固定header
+fixedHeader: ${appStore.getFixedHeader},
+// 灰色模式
+greyMode: ${appStore.getGreyMode},
+// layout布局
+layout: '${appStore.getLayout}',
+// 暗黑模式
+isDark: ${appStore.getIsDark},
+// 组件尺寸
+currentSize: '${appStore.getCurrentSize}',
+// 主题相关
+theme: {
+  // 主题色
+  elColorPrimary: '${appStore.getTheme.elColorPrimary}',
+  // 左侧菜单边框颜色
+  leftMenuBorderColor: '${appStore.getTheme.leftMenuBorderColor}',
+  // 左侧菜单背景颜色
+  leftMenuBgColor: '${appStore.getTheme.leftMenuBgColor}',
+  // 左侧菜单浅色背景颜色
+  leftMenuBgLightColor: '${appStore.getTheme.leftMenuBgLightColor}',
+  // 左侧菜单选中背景颜色
+  leftMenuBgActiveColor: '${appStore.getTheme.leftMenuBgActiveColor}',
+  // 左侧菜单收起选中背景颜色
+  leftMenuCollapseBgActiveColor: '${appStore.getTheme.leftMenuCollapseBgActiveColor}',
+  // 左侧菜单字体颜色
+  leftMenuTextColor: '${appStore.getTheme.leftMenuTextColor}',
+  // 左侧菜单选中字体颜色
+  leftMenuTextActiveColor: '${appStore.getTheme.leftMenuTextActiveColor}',
+  // logo字体颜色
+  logoTitleTextColor: '${appStore.getTheme.logoTitleTextColor}',
+  // logo边框颜色
+  logoBorderColor: '${appStore.getTheme.logoBorderColor}',
+  // 头部背景颜色
+  topHeaderBgColor: '${appStore.getTheme.topHeaderBgColor}',
+  // 头部字体颜色
+  topHeaderTextColor: '${appStore.getTheme.topHeaderTextColor}',
+  // 头部悬停颜色
+  topHeaderHoverColor: '${appStore.getTheme.topHeaderHoverColor}',
+  // 头部边框颜色
+  topToolBorderColor: '${appStore.getTheme.topToolBorderColor}'
+}
+    `
+  })
+  await copy()
+  if (unref(copied)) {
+    ElMessage.success(t('setting.copySuccess'))
+  }
+}
+
+// 清空缓存
+const clear = () => {
+  const { wsCache } = useCache()
+  wsCache.delete('layout')
+  wsCache.delete('theme')
+  wsCache.delete('isDark')
+  window.location.reload()
+}
 </script>
 
 <template>
@@ -181,6 +261,16 @@ watch(
     <!-- 界面显示 -->
     <ElDivider>{{ t('setting.interfaceDisplay') }}</ElDivider>
     <InterfaceDisplay />
+
+    <ElDivider />
+    <div>
+      <ElButton type="primary" class="w-full" @click="copyConfig">{{ t('setting.copy') }}</ElButton>
+    </div>
+    <div class="mt-5px">
+      <ElButton type="danger" class="w-full" @click="clear">
+        {{ t('setting.clearAndReset') }}
+      </ElButton>
+    </div>
   </ElDrawer>
 </template>
 

+ 0 - 1
src/components/TabMenu/src/TabMenu.vue

@@ -37,7 +37,6 @@ export default defineComponent({
       (routers: AppRouteRecordRaw[]) => {
         initTabMap(routers)
         filterMenusPath(routers, routers)
-        console.log(tabPathMap)
       },
       {
         immediate: true,

+ 7 - 7
src/config/app.ts

@@ -15,9 +15,8 @@ export interface AppState {
   tagsView: boolean
   logo: boolean
   fixedHeader: boolean
-  fixedMenu: boolean
   greyMode: boolean
-
+  pageLoading: boolean
   layout: LayoutType
   title: string
   userInfo: string
@@ -29,6 +28,12 @@ export interface AppState {
 }
 
 export const appModules: AppState = {
+  userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其他项目冲突
+  sizeMap: ['default', 'large', 'small'],
+  mobile: false, // 是否是移动端
+  title: 'ButterflyAdmin', // 标题
+  pageLoading: false, // 路由跳转loading
+
   breadcrumb: true, // 面包屑
   breadcrumbIcon: true, // 面包屑图标
   collapse: false, // 折叠菜单
@@ -39,16 +44,11 @@ export const appModules: AppState = {
   tagsView: true, // 标签页
   logo: true, // logo
   fixedHeader: true, // 固定toolheader
-  fixedMenu: false, // 固定切割菜单
   greyMode: false, // 是否开始灰色模式,用于特殊悼念日
 
   layout: wsCache.get('layout') || 'classic', // layout布局
-  title: 'ButterflyAdmin', // 标题
-  userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其他项目冲突
   isDark: wsCache.get('isDark') || false, // 是否是暗黑模式
   currentSize: wsCache.get('default') || 'default', // 组件尺寸
-  sizeMap: ['default', 'large', 'small'],
-  mobile: false, // 是否是移动端
   theme: wsCache.get('theme') || {
     // 主题色
     elColorPrimary: '#409eff',

+ 18 - 0
src/hooks/web/usePageLoading.ts

@@ -0,0 +1,18 @@
+import { useAppStoreWithOut } from '@/store/modules/app'
+
+const appStore = useAppStoreWithOut()
+
+export const usePageLoading = () => {
+  const loadStart = () => {
+    appStore.setPageLoading(true)
+  }
+
+  const loadDone = () => {
+    appStore.setPageLoading(false)
+  }
+
+  return {
+    loadStart,
+    loadDone
+  }
+}

+ 7 - 1
src/layout/components/useRenderLayout.tsx

@@ -10,6 +10,8 @@ import { ElScrollbar } from 'element-plus'
 
 const appStore = useAppStore()
 
+const pageLoading = computed(() => appStore.getPageLoading)
+
 // 标签页
 const tagsView = computed(() => appStore.getTagsView)
 
@@ -60,6 +62,7 @@ export const useRenderLayout = () => {
           style="transition: all var(--transition-time-02);"
         >
           <ElScrollbar
+            v-loading={pageLoading.value}
             class={[
               'v-content',
               {
@@ -119,6 +122,7 @@ export const useRenderLayout = () => {
             style="transition: all var(--transition-time-02);"
           >
             <ElScrollbar
+              v-loading={pageLoading.value}
               class={[
                 'v-content',
                 {
@@ -161,6 +165,7 @@ export const useRenderLayout = () => {
         </div>
         <div class="v-app-right h-full w-full">
           <ElScrollbar
+            v-loading={pageLoading.value}
             class={[
               'v-content',
               {
@@ -212,6 +217,7 @@ export const useRenderLayout = () => {
             style="transition: all var(--transition-time-02);"
           >
             <ElScrollbar
+              v-loading={pageLoading.value}
               class={[
                 'v-content',
                 {
@@ -232,7 +238,7 @@ export const useRenderLayout = () => {
                         !collapse.value && fixedHeader.value
                     }
                   ]}
-                  style="transition: all var(--transition-time-02);"
+                  style="transition: width var(--transition-time-02), left var(--transition-time-02);"
                 ></TagsView>
               ) : undefined}
 

+ 4 - 1
src/locales/en.ts

@@ -38,7 +38,10 @@ export default {
     greyMode: 'Grey mode',
     fixedHeader: 'Fixed header',
     headerTheme: 'Header theme',
-    cutMenu: 'Cut Menu'
+    cutMenu: 'Cut Menu',
+    copy: 'Copy',
+    clearAndReset: 'Clear cache and reset',
+    copySuccess: 'Copy success'
   },
   size: {
     default: 'Default',

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

@@ -38,7 +38,10 @@ export default {
     greyMode: '灰色模式',
     fixedHeader: '固定头部',
     headerTheme: '头部主题',
-    cutMenu: '切割菜单'
+    cutMenu: '切割菜单',
+    copy: '拷贝',
+    clearAndReset: '清除缓存并且重置',
+    copySuccess: '拷贝成功'
   },
   size: {
     default: '默认',

+ 5 - 0
src/permission.ts

@@ -5,6 +5,7 @@ import type { RouteRecordRaw } from 'vue-router'
 import { useTitle } from '@/hooks/web/useTitle'
 import { useNProgress } from '@/hooks/web/useNProgress'
 import { usePermissionStoreWithOut } from '@/store/modules/permission'
+import { usePageLoading } from '@/hooks/web/usePageLoading'
 
 const permissionStore = usePermissionStoreWithOut()
 
@@ -14,10 +15,13 @@ const { wsCache } = useCache()
 
 const { start, done } = useNProgress()
 
+const { loadStart, loadDone } = usePageLoading()
+
 const whiteList = ['/login'] // 不重定向白名单
 
 router.beforeEach(async (to, from, next) => {
   start()
+  loadStart()
   if (wsCache.get(appStore.getUserInfo)) {
     if (to.path === '/login') {
       next({ path: '/' })
@@ -48,4 +52,5 @@ router.beforeEach(async (to, from, next) => {
 router.afterEach((to) => {
   useTitle(to?.meta?.title as string)
   done() // 结束Progress
+  loadDone()
 })

+ 6 - 8
src/store/modules/app.ts

@@ -42,13 +42,12 @@ export const useAppStore = defineStore({
     getFixedHeader(): boolean {
       return this.fixedHeader
     },
-    getFixedMenu(): boolean {
-      return this.fixedMenu
-    },
     getGreyMode(): boolean {
       return this.greyMode
     },
-
+    getPageLoading(): boolean {
+      return this.pageLoading
+    },
     getLayout(): LayoutType {
       return this.layout
     },
@@ -105,13 +104,12 @@ export const useAppStore = defineStore({
     setFixedHeader(fixedHeader: boolean) {
       this.fixedHeader = fixedHeader
     },
-    setFixedMenu(fixedMenu: boolean) {
-      this.fixedMenu = fixedMenu
-    },
     setGreyMode(greyMode: boolean) {
       this.greyMode = greyMode
     },
-
+    setPageLoading(pageLoading: boolean) {
+      this.pageLoading = pageLoading
+    },
     setLayout(layout: LayoutType) {
       if (this.mobile && layout !== 'classic') {
         ElMessage.warning('移动端模式下不支持切换其他布局')