mirror of
				https://github.com/zclzone/vue-naive-admin.git
				synced 2025-11-01 03:39:01 +08:00 
			
		
		
		
	Merge branch '2.x-beta-theme' into 2.x-beta
This commit is contained in:
		
						commit
						1a840728a5
					
				
							
								
								
									
										13
									
								
								src/App.vue
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/App.vue
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/05 21:30:17 | ||||
|  - @LastEditTime: 2023/12/16 18:49:42 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| @ -12,7 +12,7 @@ | ||||
|     :locale="zhCN" | ||||
|     :date-locale="dateZhCN" | ||||
|     :theme="appStore.isDark ? darkTheme : undefined" | ||||
|     :theme-overrides="settings.naiveThemeOverrides" | ||||
|     :theme-overrides="appStore.naiveThemeOverrides" | ||||
|   > | ||||
|     <router-view v-if="Layout" v-slot="{ Component, route: curRoute }"> | ||||
|       <component :is="Layout"> | ||||
| @ -20,16 +20,18 @@ | ||||
|           <component :is="Component" v-if="!tabStore.reloading" :key="curRoute.fullPath" /> | ||||
|         </KeepAlive> | ||||
|       </component> | ||||
| 
 | ||||
|       <LayoutSetting class="fixed right-12 top-1/2 z-999" /> | ||||
|     </router-view> | ||||
|   </n-config-provider> | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { zhCN, dateZhCN, darkTheme } from 'naive-ui' | ||||
| import { LayoutSetting } from '@/components' | ||||
| import { useCssVar } from '@vueuse/core' | ||||
| import { kebabCase } from 'lodash-es' | ||||
| import { useAppStore, useTabStore } from '@/store' | ||||
| import settings from '@/settings' | ||||
| 
 | ||||
| const layouts = new Map() | ||||
| function getLayout(name) { | ||||
| @ -42,13 +44,14 @@ function getLayout(name) { | ||||
| 
 | ||||
| const route = useRoute() | ||||
| const appStore = useAppStore() | ||||
| if (appStore.layout === 'default') appStore.setLayout('') | ||||
| const Layout = computed(() => { | ||||
|   if (!route.matched?.length) return null | ||||
|   return getLayout(route.meta?.layout || appStore.layout || settings.defaultLayout) | ||||
|   return getLayout(route.meta?.layout || appStore.layout) | ||||
| }) | ||||
| 
 | ||||
| function setupCssVar() { | ||||
|   const common = settings.naiveThemeOverrides?.common || {} | ||||
|   const common = appStore.naiveThemeOverrides?.common || {} | ||||
|   for (const key in common) { | ||||
|     useCssVar(`--${kebabCase(key)}`, document.documentElement).value = common[key] || '' | ||||
|     if (key === 'primaryColor') window.localStorage.setItem('__THEME_COLOR__', common[key] || '') | ||||
|  | ||||
							
								
								
									
										21
									
								
								src/assets/icons/isme/theme.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/assets/icons/isme/theme.svg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| <svg | ||||
|   t="1702480351321" | ||||
|   class="icon" | ||||
|   viewBox="0 0 1024 1024" | ||||
|   version="1.1" | ||||
|   xmlns="http://www.w3.org/2000/svg" | ||||
|   p-id="11122" | ||||
|   width="200" | ||||
|   height="200" | ||||
| > | ||||
|   <path | ||||
|     d="M509.9008 519.8336m-450.816 0a450.816 450.816 0 1 0 901.632 0 450.816 450.816 0 1 0-901.632 0Z" | ||||
|     fill="#C65EDB" | ||||
|     p-id="11123" | ||||
|   ></path> | ||||
|   <path | ||||
|     d="M798.1568 512.512l-113.3056-78.3872a47.4112 47.4112 0 0 1-20.4288-39.0656l0.3584-137.7792c0.1024-39.2704-44.9024-61.5936-76.0832-37.7856l-109.568 83.5072a47.2832 47.2832 0 0 1-43.4688 7.3216l-130.9184-42.9056c-37.3248-12.2368-72.448 23.6544-59.4432 60.7232l45.568 129.9968A47.3088 47.3088 0 0 1 284.416 501.76l-81.2544 111.2576c-23.1424 31.6928 0.1024 76.2368 39.3728 75.3152l137.728-3.1744a47.3344 47.3344 0 0 1 39.4752 19.6096l80.6912 111.6672c22.9888 31.8464 72.4992 23.4496 83.7632-14.1824l37.9392-126.6176 126.5664 118.272a27.648 27.648 0 0 0 17.7664 7.4752c7.8848 0.3584 15.872-2.6112 21.7088-8.8064a27.91936 27.91936 0 0 0-1.3312-39.4752l-124.8768-116.6848 123.8016-39.8848c37.376-11.9808 44.6976-61.6448 12.3904-84.0192z m-389.6832-6.5024l-42.8032 77.824a27.86816 27.86816 0 0 1-37.9392 11.008 27.93984 27.93984 0 0 1-11.008-37.9392l40.0384-72.7552-19.0464-63.6928c-4.4032-14.7968 3.9936-30.3616 18.7392-34.7648 14.7456-4.4032 30.3616 3.9936 34.7648 18.7392l20.6848 69.2224c3.2256 10.752 1.9968 22.528-3.4304 32.3584z" | ||||
|     fill="#FFFFFF" | ||||
|     p-id="11124" | ||||
|   ></path> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.4 KiB | 
							
								
								
									
										106
									
								
								src/components/common/LayoutSetting.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/components/common/LayoutSetting.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,106 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/16 18:49:53 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| 
 | ||||
| <template> | ||||
|   <div> | ||||
|     <n-tooltip trigger="hover" placement="left"> | ||||
|       <template #trigger> | ||||
|         <i class="i-fe:settings cursor-pointer text-32 color-primary" @click="modalRef.open()" /> | ||||
|       </template> | ||||
|       布局设置 | ||||
|     </n-tooltip> | ||||
| 
 | ||||
|     <MeModal | ||||
|       ref="modalRef" | ||||
|       title="布局设置" | ||||
|       :show-footer="false" | ||||
|       width="600px" | ||||
|       :modal-style="{ opacity: 0.85 }" | ||||
|     > | ||||
|       <n-space justify="space-between"> | ||||
|         <div class="flex-col cursor-pointer justify-center" @click="appStore.setLayout('simple')"> | ||||
|           <div class="flex"> | ||||
|             <n-skeleton :width="20" :height="60" /> | ||||
|             <div class="ml-4"> | ||||
|               <n-skeleton :width="80" :height="60" /> | ||||
|             </div> | ||||
|           </div> | ||||
|           <n-button | ||||
|             class="mt-12" | ||||
|             size="small" | ||||
|             :type="appStore.layout === 'simple' ? 'primary' : ''" | ||||
|             ghost | ||||
|           > | ||||
|             简约 | ||||
|           </n-button> | ||||
|         </div> | ||||
|         <div class="flex-col cursor-pointer justify-center" @click="appStore.setLayout('normal')"> | ||||
|           <div class="flex"> | ||||
|             <n-skeleton :width="20" :height="60" /> | ||||
|             <div class="ml-4"> | ||||
|               <n-skeleton :width="80" :height="10" /> | ||||
|               <n-skeleton class="mt-4" :width="80" :height="46" /> | ||||
|             </div> | ||||
|           </div> | ||||
|           <n-button | ||||
|             class="mt-12" | ||||
|             size="small" | ||||
|             :type="appStore.layout === 'normal' ? 'primary' : ''" | ||||
|             ghost | ||||
|           > | ||||
|             通用 | ||||
|           </n-button> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="flex-col cursor-pointer justify-center" @click="appStore.setLayout('full')"> | ||||
|           <div class="flex"> | ||||
|             <n-skeleton :width="20" :height="60" /> | ||||
|             <div class="ml-4"> | ||||
|               <n-skeleton :width="80" :height="6" /> | ||||
|               <n-skeleton class="mt-4" :width="80" :height="4" /> | ||||
|               <n-skeleton class="mt-4" :width="80" :height="42" /> | ||||
|             </div> | ||||
|           </div> | ||||
|           <n-button | ||||
|             class="mt-12" | ||||
|             size="small" | ||||
|             :type="appStore.layout === 'full' ? 'primary' : ''" | ||||
|             ghost | ||||
|           > | ||||
|             全面 | ||||
|           </n-button> | ||||
|         </div> | ||||
|         <div class="flex-col cursor-pointer justify-center" @click="appStore.setLayout('empty')"> | ||||
|           <div class="flex"> | ||||
|             <n-skeleton :width="104" :height="60" /> | ||||
|           </div> | ||||
|           <n-button | ||||
|             class="mt-12" | ||||
|             size="small" | ||||
|             :type="appStore.layout === 'empty' ? 'primary' : ''" | ||||
|             ghost | ||||
|           > | ||||
|             空白 | ||||
|           </n-button> | ||||
|         </div> | ||||
|       </n-space> | ||||
|       <p class="mt-16 opacity-50"> | ||||
|         注: 此设置仅对未设置layout或者设置成跟随系统的页面有效,菜单设置的layout优先级最高 | ||||
|       </p> | ||||
|     </MeModal> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { MeModal } from '@/components' | ||||
| import { useAppStore } from '@/store' | ||||
| import { useModal } from '@/composables' | ||||
| 
 | ||||
| const appStore = useAppStore() | ||||
| const [modalRef] = useModal() | ||||
| </script> | ||||
| @ -2,3 +2,4 @@ export { default as AppCard } from './AppCard.vue' | ||||
| export { default as TheFooter } from './TheFooter.vue' | ||||
| export { default as AppPage } from './AppPage.vue' | ||||
| export { default as CommonPage } from './CommonPage.vue' | ||||
| export { default as LayoutSetting } from './LayoutSetting.vue' | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/12 09:03:22 | ||||
|  - @LastEditTime: 2023/12/16 18:50:02 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| @ -9,7 +9,7 @@ | ||||
| <template> | ||||
|   <n-modal | ||||
|     v-model:show="show" | ||||
|     :style="{ width: modalOptions.width, ...modalOptions.style }" | ||||
|     :style="{ width: modalOptions.width, ...modalOptions.modalStyle }" | ||||
|     :preset="undefined" | ||||
|     size="huge" | ||||
|     :bordered="false" | ||||
| @ -78,7 +78,7 @@ const props = defineProps({ | ||||
|     type: Boolean, | ||||
|     default: true, | ||||
|   }, | ||||
|   style: { | ||||
|   modalStyle: { | ||||
|     type: Object, | ||||
|     default: () => {}, | ||||
|   }, | ||||
| @ -104,6 +104,7 @@ const modalOptions = ref({}) | ||||
| function open(options = {}) { | ||||
|   // 将props和options合并赋值给modalOptions | ||||
|   modalOptions.value = { ...props, ...options } | ||||
| 
 | ||||
|   // 将show的值设置为true | ||||
|   show.value = true | ||||
| } | ||||
|  | ||||
							
								
								
									
										80
									
								
								src/layouts/components/BreadCrumb.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/layouts/components/BreadCrumb.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/16 18:50:10 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| 
 | ||||
| <template> | ||||
|   <n-breadcrumb> | ||||
|     <n-breadcrumb-item v-if="!breadItems?.length" :clickable="false"> | ||||
|       {{ route.meta.title }} | ||||
|     </n-breadcrumb-item> | ||||
|     <n-breadcrumb-item | ||||
|       v-for="item of breadItems" | ||||
|       v-else | ||||
|       :key="item.code" | ||||
|       :clickable="!!item.path" | ||||
|       @click="handleItemClick(item)" | ||||
|     > | ||||
|       <n-dropdown :options="getDropOptions(item.children)" @select="handleDropSelect"> | ||||
|         <div class="flex items-center"> | ||||
|           <i :class="item.icon" class="mr-8" /> | ||||
|           {{ item.name }} | ||||
|         </div> | ||||
|       </n-dropdown> | ||||
|     </n-breadcrumb-item> | ||||
|   </n-breadcrumb> | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { usePermissionStore } from '@/store' | ||||
| const router = useRouter() | ||||
| const route = useRoute() | ||||
| const permissionStore = usePermissionStore() | ||||
| 
 | ||||
| const breadItems = ref([]) | ||||
| watch( | ||||
|   () => route.name, | ||||
|   (v) => { | ||||
|     breadItems.value = findMatchs(permissionStore.permissions, v) | ||||
|   }, | ||||
|   { immediate: true } | ||||
| ) | ||||
| 
 | ||||
| function findMatchs(tree, code, parents = []) { | ||||
|   for (const item of tree) { | ||||
|     if (item.code === code) { | ||||
|       return [...parents, item] | ||||
|     } | ||||
|     if (item.children?.length) { | ||||
|       const found = findMatchs(item.children, code, [...parents, item]) | ||||
|       if (found) { | ||||
|         return found | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return null | ||||
| } | ||||
| 
 | ||||
| function handleItemClick(item) { | ||||
|   if (item.path && item.code !== route.name) { | ||||
|     router.push(item.path) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function getDropOptions(list = []) { | ||||
|   return list.map((child) => ({ | ||||
|     label: child.name, | ||||
|     key: child.code, | ||||
|     icon: () => h('i', { class: child.icon }), | ||||
|   })) | ||||
| } | ||||
| 
 | ||||
| function handleDropSelect(item) { | ||||
|   if (item.path && item.code !== route.name) { | ||||
|     router.push(item.path) | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										22
									
								
								src/layouts/components/MenuCollapse.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/layouts/components/MenuCollapse.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/16 18:50:18 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| 
 | ||||
| <template> | ||||
|   <div | ||||
|     class="f-c-c cursor-pointer rounded-4 p-6 text-22 transition-all-300 auto-bg-hover" | ||||
|     @click="appStore.switchCollapsed" | ||||
|   > | ||||
|     <i :class="appStore.collapsed ? 'i-line-md-menu-unfold-left' : 'i-line-md-menu-fold-left'" /> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { useAppStore } from '@/store' | ||||
| 
 | ||||
| const appStore = useAppStore() | ||||
| </script> | ||||
| @ -1,7 +1,7 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/05 21:23:55 | ||||
|  - @LastEditTime: 2023/12/16 18:50:28 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| @ -11,7 +11,7 @@ | ||||
|     <img src="@/assets/images/logo.png" class="h-40" /> | ||||
|     <h2 | ||||
|       v-show="!appStore.collapsed" | ||||
|       class="ml-10 max-w-140 flex-shrink-0 text-16 font-bold color-primary" | ||||
|       class="ml-10 max-w-140 flex-shrink-0 text-16 color-primary font-bold" | ||||
|     > | ||||
|       {{ title }} | ||||
|     </h2> | ||||
| @ -1,7 +1,7 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/05 21:24:02 | ||||
|  - @LastEditTime: 2023/12/16 18:50:35 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| @ -1,7 +1,7 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/05 21:23:46 | ||||
|  - @LastEditTime: 2023/12/16 18:50:42 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| @ -9,8 +9,8 @@ | ||||
| <template> | ||||
|   <n-dropdown :options="options" @select="handleSelect"> | ||||
|     <div class="flex cursor-pointer items-center"> | ||||
|       <n-avatar round :size="36" :src="userStore.avatar" class="mr-12" /> | ||||
|       <div v-if="userStore.userInfo" class="flex-col items-center"> | ||||
|       <n-avatar round :size="36" :src="userStore.avatar" /> | ||||
|       <div v-if="userStore.userInfo" class="ml-12 flex-col flex-shrink-0 items-center"> | ||||
|         <span class="text-14">{{ userStore.nickName ?? userStore.username }}</span> | ||||
|         <span class="text-12 opacity-50">[{{ userStore.currentRole?.name }}]</span> | ||||
|       </div> | ||||
| @ -1 +1,7 @@ | ||||
| export { default as RoleSelect } from './RoleSelect.vue' | ||||
| export { default as UserAvatar } from './UserAvatar.vue' | ||||
| export { default as MenuCollapse } from './MenuCollapse.vue' | ||||
| export { default as BreadCrumb } from './BreadCrumb.vue' | ||||
| export { default as AppTab } from './tab/index.vue' | ||||
| export { default as SideLogo } from './SideLogo.vue' | ||||
| export { default as SideMenu } from './SideMenu.vue' | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/05 21:23:32 | ||||
|  - @LastEditTime: 2023/12/16 18:50:48 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| @ -1,7 +1,7 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/05 21:23:38 | ||||
|  - @LastEditTime: 2023/12/16 18:50:54 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| @ -1,2 +0,0 @@ | ||||
| export { default as UserAvatar } from './UserAvatar.vue' | ||||
| export { default as AppTab } from './tab/index.vue' | ||||
							
								
								
									
										57
									
								
								src/layouts/full/header/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/layouts/full/header/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/16 18:51:10 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| 
 | ||||
| <template> | ||||
|   <AppCard class="flex items-center px-12" border-b="1px solid light_border dark:dark_border"> | ||||
|     <MenuCollapse /> | ||||
| 
 | ||||
|     <BreadCrumb /> | ||||
| 
 | ||||
|     <div class="ml-auto flex flex-shrink-0 items-center px-12 text-18"> | ||||
|       <i | ||||
|         class="mr-16 cursor-pointer" | ||||
|         :class="isDark ? 'i-fe:moon' : 'i-fe:sun'" | ||||
|         @click="toggleDark" | ||||
|       /> | ||||
|       <i | ||||
|         class="mr-16 cursor-pointer" | ||||
|         :class="isFullscreen ? 'i-fe:minimize' : 'i-fe:maximize'" | ||||
|         @click="toggle" | ||||
|       /> | ||||
| 
 | ||||
|       <i | ||||
|         class="i-fe:github mr-16 cursor-pointer" | ||||
|         @click="handleLinkClick('https://github.com/zclzone/vue-naive-admin/tree/2.x-beta')" | ||||
|       /> | ||||
|       <i | ||||
|         class="i-me:gitee mr-16 cursor-pointer" | ||||
|         @click="handleLinkClick('https://gitee.com/isme-admin/vue-naive-admin/tree/2.x-beta')" | ||||
|       /> | ||||
|       <UserAvatar /> | ||||
|     </div> | ||||
|   </AppCard> | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { MenuCollapse, UserAvatar, BreadCrumb } from '@/layouts/components' | ||||
| import { useAppStore } from '@/store' | ||||
| import { useDark, useToggle, useFullscreen } from '@vueuse/core' | ||||
| 
 | ||||
| const appStore = useAppStore() | ||||
| const isDark = useDark() | ||||
| const toggleDark = () => { | ||||
|   appStore.toggleDark() | ||||
|   useToggle(isDark)() | ||||
| } | ||||
| 
 | ||||
| const { isFullscreen, toggle } = useFullscreen() | ||||
| 
 | ||||
| function handleLinkClick(link) { | ||||
|   window.open(link) | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										42
									
								
								src/layouts/full/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/layouts/full/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/16 18:51:02 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| 
 | ||||
| <template> | ||||
|   <div class="wh-full flex"> | ||||
|     <aside | ||||
|       class="flex-col flex-shrink-0 transition-width-300" | ||||
|       :class="appStore.collapsed ? 'w-64' : 'w-220'" | ||||
|       border-r="1px solid light_border dark:dark_border" | ||||
|     > | ||||
|       <SideBar /> | ||||
|     </aside> | ||||
| 
 | ||||
|     <article class="w-0 flex-col flex-1"> | ||||
|       <AppHeader class="h-60 flex-shrink-0" /> | ||||
|       <div class="p-12" border-b="1px solid light_border dark:dark_border"> | ||||
|         <AppTab class="flex-shrink-0" /> | ||||
|       </div> | ||||
|       <slot /> | ||||
|     </article> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { useAppStore } from '@/store' | ||||
| import { AppTab } from '@/layouts/components' | ||||
| import SideBar from './sidebar/index.vue' | ||||
| import AppHeader from './header/index.vue' | ||||
| 
 | ||||
| const appStore = useAppStore() | ||||
| </script> | ||||
| 
 | ||||
| <style> | ||||
| .collapsed { | ||||
|   width: 64px; | ||||
| } | ||||
| </style> | ||||
| @ -1,17 +1,16 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/05 21:24:09 | ||||
|  - @LastEditTime: 2023/12/16 18:51:25 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| 
 | ||||
| <script setup> | ||||
| import SideLogo from './components/SideLogo.vue' | ||||
| import SideMenu from './components/SideMenu.vue' | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <SideLogo border-b="1px solid light_border dark:dark_border" /> | ||||
|   <SideMenu class="cus-scroll-y mt-4 h-0 flex-1" /> | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { SideLogo, SideMenu } from '@/layouts/components' | ||||
| </script> | ||||
| @ -1,19 +1,14 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/05 21:23:23 | ||||
|  - @LastEditTime: 2023/12/16 18:52:48 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| 
 | ||||
| <template> | ||||
|   <AppCard class="flex items-center px-12" border-b="1px solid light_border dark:dark_border"> | ||||
|     <div | ||||
|       class="f-c-c cursor-pointer rounded-4 p-6 text-22 transition-all-300 auto-bg-hover" | ||||
|       @click="appStore.switchCollapsed" | ||||
|     > | ||||
|       <i :class="appStore.collapsed ? 'i-line-md-menu-unfold-left' : 'i-line-md-menu-fold-left'" /> | ||||
|     </div> | ||||
|     <MenuCollapse /> | ||||
| 
 | ||||
|     <AppTab class="w-0 flex-1 px-12" /> | ||||
| 
 | ||||
| @ -45,9 +40,9 @@ | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { AppTab, UserAvatar } from './components' | ||||
| import { useAppStore } from '@/store' | ||||
| import { UserAvatar, MenuCollapse, AppTab } from '@/layouts/components' | ||||
| import { useDark, useToggle, useFullscreen } from '@vueuse/core' | ||||
| import { useAppStore } from '@/store' | ||||
| 
 | ||||
| const appStore = useAppStore() | ||||
| const isDark = useDark() | ||||
| @ -1,7 +1,7 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/05 21:24:19 | ||||
|  - @LastEditTime: 2023/12/13 20:54:55 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| @ -17,7 +17,7 @@ | ||||
|     </aside> | ||||
| 
 | ||||
|     <article class="w-0 flex-col flex-1"> | ||||
|       <AppHeader :class="`h-${header.height}`" class="flex-shrink-0" /> | ||||
|       <AppHeader class="h-60 flex-shrink-0" /> | ||||
|       <slot /> | ||||
|     </article> | ||||
|   </div> | ||||
| @ -28,9 +28,6 @@ import { useAppStore } from '@/store' | ||||
| import SideBar from './sidebar/index.vue' | ||||
| import AppHeader from './header/index.vue' | ||||
| 
 | ||||
| import settings from '@/settings' | ||||
| const { header } = settings | ||||
| 
 | ||||
| const appStore = useAppStore() | ||||
| </script> | ||||
| 
 | ||||
							
								
								
									
										16
									
								
								src/layouts/normal/sidebar/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/layouts/normal/sidebar/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/16 18:46:06 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| 
 | ||||
| <template> | ||||
|   <SideLogo border-b="1px solid light_border dark:dark_border" /> | ||||
|   <SideMenu class="cus-scroll-y mt-4 h-0 flex-1" /> | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { SideLogo, SideMenu } from '@/layouts/components' | ||||
| </script> | ||||
							
								
								
									
										36
									
								
								src/layouts/simple/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/layouts/simple/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/16 18:51:47 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| 
 | ||||
| <template> | ||||
|   <div class="wh-full flex"> | ||||
|     <aside | ||||
|       class="flex-col flex-shrink-0 transition-width-300" | ||||
|       :class="appStore.collapsed ? 'w-64' : 'w-220'" | ||||
|       border-r="1px solid light_border dark:dark_border" | ||||
|     > | ||||
|       <SideBar /> | ||||
|     </aside> | ||||
| 
 | ||||
|     <article class="w-0 flex-col flex-1"> | ||||
|       <slot /> | ||||
|     </article> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { useAppStore } from '@/store' | ||||
| import SideBar from './sidebar/index.vue' | ||||
| 
 | ||||
| const appStore = useAppStore() | ||||
| </script> | ||||
| 
 | ||||
| <style> | ||||
| .collapsed { | ||||
|   width: 64px; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										23
									
								
								src/layouts/simple/sidebar/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/layouts/simple/sidebar/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/05 21:24:09 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| 
 | ||||
| <template> | ||||
|   <SideLogo border-b="1px solid light_border dark:dark_border" /> | ||||
|   <SideMenu class="cus-scroll-y mt-4 h-0 flex-1" /> | ||||
|   <div class="my-12 flex items-center justify-around px-12"> | ||||
|     <UserAvatar v-if="!appStore.collapsed" /> | ||||
|     <MenuCollapse /> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { UserAvatar, MenuCollapse, SideLogo, SideMenu } from '@/layouts/components' | ||||
| import { useAppStore } from '@/store' | ||||
| 
 | ||||
| const appStore = useAppStore() | ||||
| </script> | ||||
| @ -1,21 +1,14 @@ | ||||
| /********************************** | ||||
|  * @Author: Ronnie Zhang | ||||
|  * @LastEditor: Ronnie Zhang | ||||
|  * @LastEditTime: 2023/12/05 21:30:24 | ||||
|  * @LastEditTime: 2023/12/13 20:54:36 | ||||
|  * @Email: zclzone@outlook.com | ||||
|  * Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
 | ||||
|  **********************************/ | ||||
| 
 | ||||
| export default { | ||||
|   defaultLayout: 'default', | ||||
|   header: { | ||||
|     height: 60, | ||||
|   }, | ||||
|   tab: { | ||||
|     visible: true, | ||||
|     height: 50, | ||||
|   }, | ||||
|   naiveThemeOverrides: { | ||||
| export const defaultLayout = 'normal' | ||||
| 
 | ||||
| export const naiveThemeOverrides = { | ||||
|   common: { | ||||
|     primaryColor: '#316C72FF', | ||||
|     primaryColorHover: '#316C72E3', | ||||
| @ -42,7 +35,6 @@ export default { | ||||
|     errorColorPressed: '#AB1F3FFF', | ||||
|     errorColorSuppl: '#DE576DFF', | ||||
|   }, | ||||
|   }, | ||||
| } | ||||
| 
 | ||||
| export const basePermissions = [ | ||||
|  | ||||
| @ -8,13 +8,14 @@ | ||||
| 
 | ||||
| import { defineStore } from 'pinia' | ||||
| import { useDark } from '@vueuse/core' | ||||
| import settings from '@/settings' | ||||
| import { defaultLayout, naiveThemeOverrides } from '@/settings' | ||||
| 
 | ||||
| export const useAppStore = defineStore('app', { | ||||
|   state: () => ({ | ||||
|     collapsed: false, | ||||
|     isDark: useDark(), | ||||
|     layout: settings.defaultLayout, | ||||
|     layout: defaultLayout, | ||||
|     naiveThemeOverrides, | ||||
|   }), | ||||
|   actions: { | ||||
|     switchCollapsed() { | ||||
| @ -26,12 +27,12 @@ export const useAppStore = defineStore('app', { | ||||
|     toggleDark() { | ||||
|       this.isDark = !this.isDark | ||||
|     }, | ||||
|     setDeaultLayout(v) { | ||||
|     setLayout(v) { | ||||
|       this.layout = v | ||||
|     }, | ||||
|   }, | ||||
|   persist: { | ||||
|     paths: ['layout', 'collapsed'], | ||||
|     paths: ['collapsed', 'naiveThemeOverrides'], | ||||
|     storage: localStorage, | ||||
|   }, | ||||
| }) | ||||
|  | ||||
| @ -64,7 +64,7 @@ export const usePermissionStore = defineStore('permission', { | ||||
|         meta: { | ||||
|           icon: item.icon, | ||||
|           title: item.name, | ||||
|           layout: item.layout || 'default', | ||||
|           layout: item.layout, | ||||
|           keepAlive: !!item.keepAlive, | ||||
|           parentKey, | ||||
|           btns: item.children | ||||
|  | ||||
| @ -9,7 +9,6 @@ | ||||
| 
 | ||||
| import * as NaiveUI from 'naive-ui' | ||||
| import { isNullOrUndef } from '@/utils' | ||||
| import settings from '@/settings' | ||||
| import { useAppStore } from '@/store/modules/app' | ||||
| 
 | ||||
| export function setupMessage(NMessage) { | ||||
| @ -104,10 +103,9 @@ export function setupDialog(NDialog) { | ||||
| 
 | ||||
| export function setupNaiveDiscreteApi() { | ||||
|   const appStore = useAppStore() | ||||
|   const { naiveThemeOverrides: themeOverrides } = settings | ||||
|   const configProviderProps = computed(() => ({ | ||||
|     theme: appStore.isDark ? NaiveUI.darkTheme : undefined, | ||||
|     themeOverrides, | ||||
|     themeOverrides: useAppStore().naiveThemeOverrides, | ||||
|   })) | ||||
|   const { message, dialog, notification, loadingBar } = NaiveUI.createDiscreteApi( | ||||
|     ['message', 'dialog', 'notification', 'loadingBar'], | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <!-------------------------------- | ||||
|  - @Author: Ronnie Zhang | ||||
|  - @LastEditor: Ronnie Zhang | ||||
|  - @LastEditTime: 2023/12/05 21:27:43 | ||||
|  - @LastEditTime: 2023/12/16 18:51:56 | ||||
|  - @Email: zclzone@outlook.com | ||||
|  - Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top | ||||
|  ---------------------------------> | ||||
| @ -32,6 +32,10 @@ function openModal1() { | ||||
|     okText: '再弹个窗', | ||||
|     cancelText: '关闭', | ||||
|     async onOk() { | ||||
|       if (!text.value) { | ||||
|         $message.warning('请输入内容') | ||||
|         return false // 阻止弹窗关闭 | ||||
|       } | ||||
|       okLoading1.value = true | ||||
|       $message.loading('正在提交...', { key: 'modal1' }) | ||||
|       await sleep(1000) | ||||
| @ -48,16 +52,10 @@ function openModal1() { | ||||
| 
 | ||||
| const [$modal2, okLoading2] = useModal() | ||||
| function openModal2() { | ||||
|   // modal的options都是可变的 | ||||
|   if ($modal1.value) { | ||||
|     $modal1.value.options.style.top = '-100px' | ||||
|     $modal1.value.options.title = '我走了' | ||||
|   } | ||||
| 
 | ||||
|   $modal2.value?.open({ | ||||
|     cancelText: '关闭当前', | ||||
|     okText: '关闭所有弹窗', | ||||
|     style: { width: '320px', padding: '12px', top: '100px' }, | ||||
|     modalStyle: { width: '320px', padding: '12px', top: '100px' }, | ||||
|     async onOk() { | ||||
|       okLoading2.value = true | ||||
|       $message.loading('正在关闭...', { key: 'modal2' }) | ||||
| @ -68,12 +66,6 @@ function openModal2() { | ||||
|       $modal1.value?.close() | ||||
|       $message.success('已关闭', { key: 'modal2' }) | ||||
|     }, | ||||
|     onCancel() { | ||||
|       if ($modal1.value) { | ||||
|         $modal1.value.options.style.top = '0' | ||||
|         $modal1.value.options.title = '我又回来了' | ||||
|       } | ||||
|     }, | ||||
|   }) | ||||
| } | ||||
| </script> | ||||
|  | ||||
| @ -155,7 +155,10 @@ const iconOptions = icons.map((item) => ({ | ||||
|   value: item, | ||||
| })) | ||||
| const layoutOptions = [ | ||||
|   { label: '默认-default', value: 'default' }, | ||||
|   { label: '跟随系统', value: '' }, | ||||
|   { label: '简约-simple', value: 'simple' }, | ||||
|   { label: '通用-normal', value: 'normal' }, | ||||
|   { label: '全面-full', value: 'full' }, | ||||
|   { label: '空白-empty', value: 'empty' }, | ||||
| ] | ||||
| const required = { | ||||
|  | ||||
| @ -49,7 +49,7 @@ | ||||
|               <span v-else>无</span> | ||||
|             </n-descriptions-item> | ||||
|             <n-descriptions-item label="layout"> | ||||
|               {{ currentMenu.layout ?? 'default' }} | ||||
|               {{ currentMenu.layout || '跟随系统' }} | ||||
|             </n-descriptions-item> | ||||
|             <n-descriptions-item label="是否显示"> | ||||
|               {{ currentMenu.show ? '是' : '否' }} | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user