refactor(projects): all file and folder use kebab-case

This commit is contained in:
Soybean
2023-02-23 08:22:44 +08:00
parent bf2f617255
commit cea600f12c
138 changed files with 130 additions and 155 deletions

View File

@ -0,0 +1,4 @@
import VerticalSider from './vertical-sider/index.vue';
import VerticalMixSider from './vertical-mix-sider/index.vue';
export { VerticalSider, VerticalMixSider };

View File

@ -0,0 +1,5 @@
import MixMenuDetail from './mix-menu-detail.vue';
import MixMenuDrawer from './mix-menu-drawer.vue';
import MixMenuCollapse from './mix-menu-collapse.vue';
export { MixMenuDetail, MixMenuDrawer, MixMenuCollapse };

View File

@ -0,0 +1,16 @@
<template>
<n-button :text="true" class="h-36px" @click="app.toggleSiderCollapse">
<icon-ph-caret-double-right-bold v-if="app.siderCollapse" class="text-16px" />
<icon-ph-caret-double-left-bold v-else class="text-16px" />
</n-button>
</template>
<script lang="ts" setup>
import { useAppStore } from '@/store';
defineOptions({ name: 'MixMenuCollapse' });
const app = useAppStore();
</script>
<style scoped></style>

View File

@ -0,0 +1,48 @@
<template>
<div class="mb-6px px-4px cursor-pointer" @mouseenter="setTrue" @mouseleave="setFalse">
<div
class="flex-center flex-col py-12px rounded-2px bg-transparent transition-colors duration-300 ease-in-out"
:class="{ 'text-primary !bg-primary_active': isActive, 'text-primary': isHover }"
>
<component :is="icon" :class="[isMini ? 'text-16px' : 'text-20px']" />
<p
class="text-12px overflow-hidden transition-height duration-300 ease-in-out"
:class="[isMini ? 'h-0 pt-0' : 'h-24px pt-4px']"
>
{{ label }}
</p>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import type { VNodeChild } from 'vue';
import { useBoolean } from '@/hooks';
defineOptions({ name: 'MixMenuDetail' });
interface Props {
/** 路由名称 */
routeName: string;
/** 路由名称文本 */
label: string;
/** 当前激活状态的理由名称 */
activeRouteName: string;
/** 路由图标 */
icon?: () => VNodeChild;
/** mini尺寸的路由 */
isMini?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
icon: undefined,
isMini: false
});
const { bool: isHover, setTrue, setFalse } = useBoolean();
const isActive = computed(() => props.routeName === props.activeRouteName);
</script>
<style scoped></style>

View File

@ -0,0 +1,83 @@
<template>
<div
class="relative h-full transition-width duration-300 ease-in-out"
:style="{ width: app.mixSiderFixed ? theme.sider.mixChildMenuWidth + 'px' : '0px' }"
>
<dark-mode-container
class="drawer-shadow absolute-lt flex-col-stretch h-full nowrap-hidden"
:style="{ width: showDrawer ? theme.sider.mixChildMenuWidth + 'px' : '0px' }"
>
<header class="header-height flex-y-center justify-between" :style="{ height: theme.header.height + 'px' }">
<h2 class="text-primary pl-8px text-16px font-bold">{{ title }}</h2>
<div class="px-8px text-16px text-gray-600 cursor-pointer" @click="app.toggleMixSiderFixed">
<icon-mdi-pin-off v-if="app.mixSiderFixed" />
<icon-mdi-pin v-else />
</div>
</header>
<n-scrollbar class="flex-1-hidden">
<n-menu
:value="activeKey"
:options="menus"
:expanded-keys="expandedKeys"
:indent="18"
@update:value="handleUpdateMenu"
@update:expanded-keys="handleUpdateExpandedKeys"
/>
</n-scrollbar>
</dark-mode-container>
</div>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import type { MenuOption } from 'naive-ui';
import { useAppStore, useThemeStore } from '@/store';
import { useAppInfo, useRouterPush } from '@/composables';
import { getActiveKeyPathsOfMenus } from '@/utils';
defineOptions({ name: 'MixMenuDrawer' });
interface Props {
/** 菜单抽屉可见性 */
visible: boolean;
/** 子菜单数据 */
menus: App.GlobalMenuOption[];
}
const props = defineProps<Props>();
const route = useRoute();
const app = useAppStore();
const theme = useThemeStore();
const { routerPush } = useRouterPush();
const { title } = useAppInfo();
const showDrawer = computed(() => (props.visible && props.menus.length) || app.mixSiderFixed);
const activeKey = computed(() => (route.meta?.activeMenu ? route.meta.activeMenu : route.name) as string);
const expandedKeys = ref<string[]>([]);
function handleUpdateMenu(_key: string, item: MenuOption) {
const menuItem = item as App.GlobalMenuOption;
routerPush(menuItem.routePath);
}
function handleUpdateExpandedKeys(keys: string[]) {
expandedKeys.value = keys;
}
watch(
() => route.name,
() => {
expandedKeys.value = getActiveKeyPathsOfMenus(activeKey.value, props.menus);
},
{ immediate: true }
);
</script>
<style scoped>
.drawer-shadow {
box-shadow: 2px 0 8px 0 rgb(29 35 41 / 5%);
}
</style>

View File

@ -0,0 +1,107 @@
<template>
<dark-mode-container class="flex h-full" :inverted="theme.sider.inverted" @mouseleave="resetFirstDegreeMenus">
<div class="flex-1 flex-col-stretch h-full">
<global-logo :show-title="false" :style="{ height: theme.header.height + 'px' }" />
<n-scrollbar class="flex-1-hidden">
<mix-menu-detail
v-for="item in firstDegreeMenus"
:key="item.routeName"
:route-name="item.routeName"
:active-route-name="activeParentRouteName"
:label="item.label"
:icon="item.icon"
:is-mini="app.siderCollapse"
@click="handleMixMenu(item.routeName, item.hasChildren)"
/>
</n-scrollbar>
<mix-menu-collapse />
</div>
<mix-menu-drawer :visible="drawerVisible" :menus="activeChildMenus" />
</dark-mode-container>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import { useAppStore, useRouteStore, useThemeStore } from '@/store';
import { useRouterPush } from '@/composables';
import { useBoolean } from '@/hooks';
import { GlobalLogo } from '@/layouts/common';
import { MixMenuCollapse, MixMenuDetail, MixMenuDrawer } from './components';
defineOptions({ name: 'VerticalMixSider' });
const route = useRoute();
const app = useAppStore();
const theme = useThemeStore();
const routeStore = useRouteStore();
const { routerPush } = useRouterPush();
const { bool: drawerVisible, setTrue: openDrawer, setFalse: hideDrawer } = useBoolean();
const activeParentRouteName = ref('');
function setActiveParentRouteName(routeName: string) {
activeParentRouteName.value = routeName;
}
const firstDegreeMenus = computed(() =>
routeStore.menus.map(item => {
const { routeName, label } = item;
const icon = item?.icon;
const hasChildren = Boolean(item.children && item.children.length);
return {
routeName,
label,
icon,
hasChildren
};
})
);
function getActiveParentRouteName() {
firstDegreeMenus.value.some(item => {
const routeName = (route.meta?.activeMenu ? route.meta.activeMenu : route.name) as string;
const flag = routeName?.includes(item.routeName);
if (flag) {
setActiveParentRouteName(item.routeName);
}
return flag;
});
}
function handleMixMenu(routeName: string, hasChildren: boolean) {
setActiveParentRouteName(routeName);
if (hasChildren) {
openDrawer();
} else {
routerPush({ name: routeName });
}
}
function resetFirstDegreeMenus() {
getActiveParentRouteName();
hideDrawer();
}
const activeChildMenus = computed(() => {
const menus: App.GlobalMenuOption[] = [];
routeStore.menus.some(item => {
const flag = item.routeName === activeParentRouteName.value && Boolean(item.children?.length);
if (flag) {
menus.push(...(item.children || []));
}
return flag;
});
return menus;
});
watch(
() => route.name,
() => {
getActiveParentRouteName();
},
{ immediate: true }
);
</script>
<style scoped></style>

View File

@ -0,0 +1,3 @@
import VerticalMenu from './vertical-menu.vue';
export { VerticalMenu };

View File

@ -0,0 +1,57 @@
<template>
<n-scrollbar class="flex-1-hidden">
<n-menu
:value="activeKey"
:collapsed="app.siderCollapse"
:collapsed-width="theme.sider.collapsedWidth"
:collapsed-icon-size="22"
:options="menus"
:expanded-keys="expandedKeys"
:indent="18"
:inverted="theme.sider.inverted"
@update:value="handleUpdateMenu"
@update:expanded-keys="handleUpdateExpandedKeys"
/>
</n-scrollbar>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import type { MenuOption } from 'naive-ui';
import { useAppStore, useRouteStore, useThemeStore } from '@/store';
import { useRouterPush } from '@/composables';
import { getActiveKeyPathsOfMenus } from '@/utils';
defineOptions({ name: 'VerticalMenu' });
const route = useRoute();
const app = useAppStore();
const theme = useThemeStore();
const routeStore = useRouteStore();
const { routerPush } = useRouterPush();
const menus = computed(() => routeStore.menus as App.GlobalMenuOption[]);
const activeKey = computed(() => (route.meta?.activeMenu ? route.meta.activeMenu : route.name) as string);
const expandedKeys = ref<string[]>([]);
function handleUpdateMenu(_key: string, item: MenuOption) {
const menuItem = item as App.GlobalMenuOption;
routerPush(menuItem.routePath);
}
function handleUpdateExpandedKeys(keys: string[]) {
expandedKeys.value = keys;
}
watch(
() => route.name,
() => {
expandedKeys.value = getActiveKeyPathsOfMenus(activeKey.value, menus.value);
},
{ immediate: true }
);
</script>
<style scoped></style>

View File

@ -0,0 +1,23 @@
<template>
<dark-mode-container class="flex-col-stretch h-full" :inverted="theme.sider.inverted">
<global-logo v-if="!isHorizontalMix" :show-title="showTitle" :style="{ height: theme.header.height + 'px' }" />
<vertical-menu />
</dark-mode-container>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { useAppStore, useThemeStore } from '@/store';
import { GlobalLogo } from '@/layouts/common';
import { VerticalMenu } from './components';
defineOptions({ name: 'VerticalSider' });
const app = useAppStore();
const theme = useThemeStore();
const isHorizontalMix = computed(() => theme.layout.mode === 'horizontal-mix');
const showTitle = computed(() => !app.siderCollapse && theme.layout.mode !== 'vertical-mix');
</script>
<style scoped></style>

View File

@ -0,0 +1,22 @@
<template>
<vertical-mix-sider v-if="isVerticalMix" class="global-sider" />
<vertical-sider v-else class="global-sider" />
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { useThemeStore } from '@/store';
import { VerticalMixSider, VerticalSider } from './components';
defineOptions({ name: 'GlobalSider' });
const theme = useThemeStore();
const isVerticalMix = computed(() => theme.layout.mode === 'vertical-mix');
</script>
<style scoped>
.global-sider {
box-shadow: 2px 0 8px 0 rgb(29 35 41 / 5%);
}
</style>