feat: 页面基础框架

This commit is contained in:
2024-08-27 20:59:54 +08:00
parent 8c91c76adc
commit 2327d1c8bb
3 changed files with 196 additions and 14 deletions

View File

@@ -3,13 +3,22 @@
:date-locale="configProviderProps.dateLocale"
:inline-theme-disabled="configProviderProps.inlineThemeDisabled"
:locale="configProviderProps.locale"
:style="{
'--color-error': themeVars.errorColor,
'--color-info': themeVars.infoColor,
'--color-primary': themeVars.primaryColor,
'--color-success': themeVars.successColor,
'--color-warning': themeVars.warningColor,
}"
>
<!-- Naive UI 全局样式 -->
<n-global-style></n-global-style>
<!-- 全局侧边栏 -->
<div class="app-aside"></div>
<div class="app-aside-wrapper">
<app-aside />
</div>
<!-- 路由页面 -->
<router-view class="app-view"></router-view>
@@ -19,12 +28,17 @@
<script setup>
import {
NConfigProvider, NGlobalStyle,
NConfigProvider, NGlobalStyle, useThemeVars,
} from 'naive-ui';
import {
configProviderProps,
} from './assets/js/naive-ui';
import AppAside from './components/AppAside.vue';
/** 主题变量 */
const themeVars = useThemeVars();
</script>
<style lang="less">
@@ -73,6 +87,7 @@ html {
background-color: #FFF;
color: var(--color-black);
font-size: 16px;
line-height: 1;
}
.n-config-provider {
@@ -84,8 +99,9 @@ html {
height: 100%;
}
.app-aside {
width: 80px;
.app-aside-wrapper {
width: 64px;
border-right: 1px solid var(--color-gray);
}
.app-view {

141
src/components/AppAside.vue Normal file
View File

@@ -0,0 +1,141 @@
<template>
<!-- 侧边栏 -->
<div class="app-aside">
<div class="app-icon-wrapper">
<div class="app-icon"></div>
</div>
<div class="app-modules">
<div
v-for="item in modules"
:key="item.name"
:title="item.title"
:class="{
'is-active': (currRouteName === item.name),
'module-item': true,
}"
@click="changePage(item.name)"
>
<span :class="item.className"></span>
</div>
</div>
</div>
</template>
<script setup>
import {
computed, shallowRef, onBeforeMount,
} from 'vue';
import {
useRoute, useRouter,
} from 'vue-router';
/** 当前路由名称 */
const currRouteName = computed(() => {
return route.name;
});
/**
* @desc 模块列表
* @type {VueRef<{ className: string; name: string; title: string; }[]>}
*/
const modules = shallowRef([]);
/** 路由 */
const route = useRoute();
/** 路由 */
const router = useRouter();
/** 切换页面 */
function changePage(routeName = '') {
router.replace({ name: routeName });
}
/** 初始化数据 */
function initData() {
/** @type {typeof modules.value} */
let list = [];
// 提取路由信息
router.getRoutes().forEach((item) => {
let m = item.meta;
if (m.showInAside) {
list.push({
className: m.iconClass,
name: item.name,
title: m.title,
});
}
});
modules.value = list;
}
onBeforeMount(() => {
initData();
});
</script>
<style lang="less" scoped>
.app-aside {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.app-icon-wrapper {
display: flex;
flex-direction: column;
margin-top: 24px;
}
.app-icon {
margin: auto;
width: 32px;
height: 32px;
background-image: url("./favicon.ico");
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
.app-modules {
display: flex;
flex-direction: column;
margin-top: 48px;
}
.module-item {
display: flex;
margin: 0 auto;
width: 1.8em;
height: 1.8em;
border-radius: 50%;
color: #808080;
font-size: 24px;
cursor: pointer;
&:not(:first-child) {
margin-top: 10px;
}
&:hover, &.is-active {
background-color: #F2F2F2;
color: var(--color-info);
}
span {
margin: auto;
}
}
</style>

View File

@@ -10,26 +10,51 @@ export const router = createRouter({
path: '/',
name: 'IndexView',
component: IndexView,
},
{
path: '/about-view',
name: 'AboutView',
component: AboutView,
},
{
path: '/nav-view',
name: 'NavView',
component: () => import('@/views/NavView/NavView.vue'),
meta: {
iconClass: 'mdi mdi-home-outline',
showInAside: true,
title: '主页',
},
},
{
path: '/search-view',
name: 'SearchView',
component: () => import('@/views/SearchView/SearchView.vue'),
meta: {
iconClass: 'mdi mdi-magnify',
showInAside: true,
title: '搜索',
},
},
{
path: '/nav-view',
name: 'NavView',
component: () => import('@/views/NavView/NavView.vue'),
meta: {
iconClass: 'mdi mdi-compass-outline',
showInAside: true,
title: '导航',
},
},
{
path: '/toolbox-view',
name: 'ToolboxView',
component: () => import('@/views/ToolboxView/ToolboxView.vue'),
meta: {
iconClass: 'mdi mdi-tools',
showInAside: true,
title: '工具箱',
},
},
{
path: '/about-view',
name: 'AboutView',
component: AboutView,
meta: {
iconClass: 'mdi mdi-information-outline',
showInAside: true,
title: '关于',
},
},
],
});