mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-24 07:49:47 +08:00
refactor(projects): perf code
This commit is contained in:
@ -10,7 +10,7 @@ import GlobalTab from '../modules/global-tab/index.vue';
|
||||
import GlobalContent from '../modules/global-content/index.vue';
|
||||
import GlobalFooter from '../modules/global-footer/index.vue';
|
||||
import ThemeDrawer from '../modules/theme-drawer/index.vue';
|
||||
import { setupMixMenuContext } from '../hooks/use-mix-menu';
|
||||
import { setupMixMenuContext } from '../context';
|
||||
|
||||
defineOptions({
|
||||
name: 'BaseLayout'
|
||||
|
4
src/layouts/context/index.ts
Normal file
4
src/layouts/context/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { useContext } from '@sa/hooks';
|
||||
import { useMixMenu } from '../hooks';
|
||||
|
||||
export const { setupStore: setupMixMenuContext, useStore: useMixMenuContext } = useContext('mix-menu', useMixMenu);
|
@ -1,6 +1,5 @@
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useContext } from '@sa/hooks';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
|
||||
export function useMixMenu() {
|
||||
@ -43,5 +42,3 @@ export function useMixMenu() {
|
||||
menus
|
||||
};
|
||||
}
|
||||
|
||||
export const { setupStore: setupMixMenuContext, useStore: useMixMenuContext } = useContext('mix-menu', useMixMenu);
|
@ -26,14 +26,14 @@ function handleClickMenu(key: RouteKey) {
|
||||
|
||||
<template>
|
||||
<NBreadcrumb v-if="themeStore.header.breadcrumb.visible">
|
||||
<!-- define component: BreadcrumbContent -->
|
||||
<!-- define component start: BreadcrumbContent -->
|
||||
<DefineBreadcrumbContent v-slot="{ breadcrumb }">
|
||||
<div class="i-flex-y-center align-middle">
|
||||
<component :is="breadcrumb.icon" v-if="themeStore.header.breadcrumb.showIcon" class="mr-4px text-icon" />
|
||||
{{ breadcrumb.label }}
|
||||
</div>
|
||||
</DefineBreadcrumbContent>
|
||||
<!-- define component: BreadcrumbContent -->
|
||||
<!-- define component end: BreadcrumbContent -->
|
||||
|
||||
<NBreadcrumbItem v-for="item in routeStore.breadcrumbs" :key="item.key">
|
||||
<NDropdown v-if="item.options?.length" :options="item.options" @select="handleClickMenu">
|
||||
|
@ -1,11 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { VNode } from 'vue';
|
||||
import { useSvgIconRender } from '@sa/hooks';
|
||||
import { useAuthStore } from '@/store/modules/auth';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { useSvgIcon } from '@/hooks/common/icon';
|
||||
import { $t } from '@/locales';
|
||||
import SvgIcon from '@/components/custom/svg-icon.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'UserAvatar'
|
||||
@ -13,7 +12,7 @@ defineOptions({
|
||||
|
||||
const authStore = useAuthStore();
|
||||
const { routerPushByKey, toLogin } = useRouterPush();
|
||||
const { SvgIconVNode } = useSvgIconRender(SvgIcon);
|
||||
const { SvgIconVNode } = useSvgIcon();
|
||||
|
||||
function loginOrRegister() {
|
||||
toLogin();
|
||||
|
@ -8,7 +8,7 @@ import HorizontalMenu from '../global-menu/base-menu.vue';
|
||||
import GlobalLogo from '../global-logo/index.vue';
|
||||
import GlobalBreadcrumb from '../global-breadcrumb/index.vue';
|
||||
import GlobalSearch from '../global-search/index.vue';
|
||||
import { useMixMenuContext } from '../../hooks/use-mix-menu';
|
||||
import { useMixMenuContext } from '../../context';
|
||||
import ThemeButton from './components/theme-button.vue';
|
||||
import UserAvatar from './components/user-avatar.vue';
|
||||
|
||||
|
@ -58,7 +58,7 @@ function handleClickMixMenu(menu: App.Global.Menu) {
|
||||
<!-- define component: MixMenuItem -->
|
||||
<DefineMixMenuItem v-slot="{ label, icon, active, isMini }">
|
||||
<div
|
||||
class="mx-4px mb-6px flex-vertical-center cursor-pointer rounded-8px bg-transparent px-4px py-8px transition-300 hover:bg-[rgb(0,0,0,0.08)]"
|
||||
class="mx-4px mb-6px flex-col-center cursor-pointer rounded-8px bg-transparent px-4px py-8px transition-300 hover:bg-[rgb(0,0,0,0.08)]"
|
||||
:class="{
|
||||
'text-primary selected-mix-menu': active,
|
||||
'text-white:65 hover:text-white': inverted,
|
||||
@ -74,9 +74,9 @@ function handleClickMixMenu(menu: App.Global.Menu) {
|
||||
</p>
|
||||
</div>
|
||||
</DefineMixMenuItem>
|
||||
<!-- define component end: MixMenuItem -->
|
||||
|
||||
<!-- template -->
|
||||
<div class="h-full flex-vertical-stretch flex-1-hidden">
|
||||
<div class="h-full flex-col-stretch flex-1-hidden">
|
||||
<slot></slot>
|
||||
<SimpleScrollbar>
|
||||
<MixMenuItem
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { useMixMenuContext } from '../../hooks/use-mix-menu';
|
||||
import { useMixMenuContext } from '../../context';
|
||||
import FirstLevelMenu from './first-level-menu.vue';
|
||||
|
||||
defineOptions({
|
||||
|
@ -5,7 +5,7 @@ import { useAppStore } from '@/store/modules/app';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { useMixMenu } from '../../hooks/use-mix-menu';
|
||||
import { useMixMenu } from '../../hooks';
|
||||
import FirstLevelMenu from './first-level-menu.vue';
|
||||
import BaseMenu from './base-menu.vue';
|
||||
|
||||
@ -52,7 +52,7 @@ function handleResetActiveMenu() {
|
||||
:style="{ width: appStore.mixSiderFixed ? themeStore.sider.mixChildMenuWidth + 'px' : '0px' }"
|
||||
>
|
||||
<DarkModeContainer
|
||||
class="absolute-lt h-full flex-vertical-stretch nowrap-hidden shadow-sm transition-all-300"
|
||||
class="absolute-lt h-full flex-col-stretch nowrap-hidden shadow-sm transition-all-300"
|
||||
:inverted="siderInverted"
|
||||
:style="{ width: showDrawer ? themeStore.sider.mixChildMenuWidth + 'px' : '0px' }"
|
||||
>
|
||||
|
@ -31,6 +31,6 @@ defineOptions({ name: 'SearchFooter' });
|
||||
}
|
||||
|
||||
.operate-item {
|
||||
--at-apply: mr-6px p-2px text-20px;
|
||||
--uno: mr-6px p-2px text-20px;
|
||||
}
|
||||
</style>
|
||||
|
@ -23,7 +23,7 @@ const showLogo = computed(() => !isVerticalMix.value && !isHorizontalMix.value);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DarkModeContainer class="size-full flex-vertical-stretch shadow-sider" :inverted="darkMenu">
|
||||
<DarkModeContainer class="size-full flex-col-stretch shadow-sider" :inverted="darkMenu">
|
||||
<GlobalLogo
|
||||
v-if="showLogo"
|
||||
:show-title="!appStore.siderCollapse"
|
||||
|
@ -1,10 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { VNode } from 'vue';
|
||||
import { useSvgIconRender } from '@sa/hooks';
|
||||
import { $t } from '@/locales';
|
||||
import { useTabStore } from '@/store/modules/tab';
|
||||
import SvgIcon from '@/components/custom/svg-icon.vue';
|
||||
import { useSvgIcon } from '@/hooks/common/icon';
|
||||
|
||||
defineOptions({
|
||||
name: 'ContextMenu'
|
||||
@ -28,7 +27,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
const visible = defineModel<boolean>('visible');
|
||||
|
||||
const { removeTab, clearTabs, clearLeftTabs, clearRightTabs } = useTabStore();
|
||||
const { SvgIconVNode } = useSvgIconRender(SvgIcon);
|
||||
const { SvgIconVNode } = useSvgIcon();
|
||||
|
||||
type DropdownOption = {
|
||||
key: App.Global.DropdownKey;
|
||||
|
@ -199,7 +199,7 @@ init();
|
||||
:x="dropdown.x"
|
||||
:y="dropdown.y"
|
||||
@update:visible="handleDropdownVisible"
|
||||
></ContextMenu>
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
@ -80,7 +80,7 @@ function handleChangeMode(mode: UnionKey.ThemeLayoutMode) {
|
||||
<template #trigger>
|
||||
<div
|
||||
class="h-64px w-96px gap-6px rd-4px p-6px shadow dark:shadow-coolGray-5"
|
||||
:class="[key.includes('vertical') ? 'flex' : 'flex-vertical']"
|
||||
:class="[key.includes('vertical') ? 'flex' : 'flex-col']"
|
||||
>
|
||||
<slot :name="key"></slot>
|
||||
</div>
|
||||
|
@ -26,7 +26,7 @@ const showSiderInverted = computed(() => !themeStore.darkMode && themeStore.layo
|
||||
|
||||
<template>
|
||||
<NDivider>{{ $t('theme.themeSchema.title') }}</NDivider>
|
||||
<div class="flex-vertical-stretch gap-16px">
|
||||
<div class="flex-col-stretch gap-16px">
|
||||
<div class="i-flex-center">
|
||||
<NTabs
|
||||
:key="themeStore.themeScheme"
|
||||
@ -50,20 +50,13 @@ const showSiderInverted = computed(() => !themeStore.darkMode && themeStore.layo
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.sider-inverted-enter-active {
|
||||
height: 22px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.sider-inverted-enter-active,
|
||||
.sider-inverted-leave-active {
|
||||
height: 22px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
--uno: h-22px transition-all-300;
|
||||
}
|
||||
|
||||
.sider-inverted-enter-from,
|
||||
.sider-inverted-leave-to {
|
||||
transform: translateX(20px);
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
--uno: translate-x-20px opacity-0 h-0;
|
||||
}
|
||||
</style>
|
||||
|
@ -60,7 +60,7 @@ const themeStore = useThemeStore();
|
||||
}
|
||||
|
||||
.vertical-wrapper {
|
||||
--uno: flex-1 flex-vertical gap-6px;
|
||||
--uno: flex-1 flex-col gap-6px;
|
||||
}
|
||||
|
||||
.horizontal-wrapper {
|
||||
|
@ -21,14 +21,14 @@ const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wra
|
||||
|
||||
<template>
|
||||
<NDivider>{{ $t('theme.pageFunTitle') }}</NDivider>
|
||||
<TransitionGroup tag="div" name="setting-list" class="flex-vertical-stretch gap-12px">
|
||||
<TransitionGroup tag="div" name="setting-list" class="flex-col-stretch gap-12px">
|
||||
<SettingItem key="1" :label="$t('theme.scrollMode.title')">
|
||||
<NSelect
|
||||
v-model:value="themeStore.layout.scrollMode"
|
||||
:options="translateOptions(themeScrollModeOptions)"
|
||||
size="small"
|
||||
class="w-120px"
|
||||
></NSelect>
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem key="1-1" :label="$t('theme.page.animate')">
|
||||
<NSwitch v-model:value="themeStore.page.animate" />
|
||||
@ -108,16 +108,15 @@ const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wra
|
||||
.setting-list-move,
|
||||
.setting-list-enter-active,
|
||||
.setting-list-leave-active {
|
||||
transition: all 0.3s ease-in-out;
|
||||
--uno: transition-all-300;
|
||||
}
|
||||
|
||||
.setting-list-enter-from,
|
||||
.setting-list-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(-30px);
|
||||
--uno: opacity-0 -translate-x-30px;
|
||||
}
|
||||
|
||||
.setting-list-leave-active {
|
||||
position: absolute;
|
||||
--uno: absolute;
|
||||
}
|
||||
</style>
|
||||
|
@ -35,7 +35,7 @@ const swatches: string[] = [
|
||||
|
||||
<template>
|
||||
<NDivider>{{ $t('theme.themeColor.title') }}</NDivider>
|
||||
<div class="flex-vertical-stretch gap-12px">
|
||||
<div class="flex-col-stretch gap-12px">
|
||||
<SettingItem v-for="(_, key) in themeStore.themeColors" :key="key" :label="$t(`theme.themeColor.${key}`)">
|
||||
<template v-if="key === 'info'" #suffix>
|
||||
<NCheckbox v-model:checked="themeStore.isInfoFollowPrimary">
|
||||
|
Reference in New Issue
Block a user