feat(projects): 新增网址导航页面
This commit is contained in:
parent
98a7d25cf8
commit
32aa5ee75a
39
src/components/custom/ThemeSwitch/index.vue
Normal file
39
src/components/custom/ThemeSwitch/index.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="flex-center w-40px h-40px text-14px hover:text-primary cursor-pointer" @click="toggleDarkMode">
|
||||
<icon-mdi-moon-waning-crescent v-if="dark" />
|
||||
<icon-mdi-white-balance-sunny v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { watch } from 'vue';
|
||||
import { useBoolean } from '@/hooks';
|
||||
|
||||
interface Props {
|
||||
/** 暗黑模式 */
|
||||
dark?: boolean;
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update', darkMode: boolean): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
dark: false
|
||||
});
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const { bool: darkMode, setBool: setDarkMode, toggle: toggleDarkMode } = useBoolean(props.dark);
|
||||
|
||||
watch(
|
||||
() => props.dark,
|
||||
newValue => {
|
||||
setDarkMode(newValue);
|
||||
}
|
||||
);
|
||||
watch(darkMode, newValue => {
|
||||
emit('update', newValue);
|
||||
});
|
||||
</script>
|
||||
<style scoped></style>
|
@ -5,5 +5,6 @@ import ChromeTab from './ChromeTab/index.vue';
|
||||
import BetterScroll from './BetterScroll/index.vue';
|
||||
import WebSiteLink from './WebSiteLink/index.vue';
|
||||
import GithubLink from './GithubLink/index.vue';
|
||||
import ThemeSwitch from './ThemeSwitch/index.vue';
|
||||
|
||||
export { CountTo, IconClose, ButtonTab, ChromeTab, BetterScroll, WebSiteLink, GithubLink };
|
||||
export { CountTo, IconClose, ButtonTab, ChromeTab, BetterScroll, WebSiteLink, GithubLink, ThemeSwitch };
|
||||
|
@ -1,2 +1,3 @@
|
||||
export * from './auth';
|
||||
export * from './demo';
|
||||
export * from './website';
|
||||
|
18
src/interface/business/website.ts
Normal file
18
src/interface/business/website.ts
Normal file
@ -0,0 +1,18 @@
|
||||
/** 网址导航 */
|
||||
export interface Website {
|
||||
/** 网址名称 */
|
||||
title: string;
|
||||
/** 网址简称 */
|
||||
abbr: string;
|
||||
/** 网址图标(网络地址,形状为正方形) */
|
||||
logo: string;
|
||||
/** 描述 */
|
||||
desc: string;
|
||||
}
|
||||
|
||||
/** 网址导航 分类 */
|
||||
export interface WebsiteCategory {
|
||||
/** 分类名称 */
|
||||
title: string;
|
||||
children: WebsiteCategory[] | Website[];
|
||||
}
|
@ -55,4 +55,5 @@ export type RouteKey =
|
||||
| 'exception_403'
|
||||
| 'exception_404'
|
||||
| 'exception_500'
|
||||
| 'about';
|
||||
| 'about'
|
||||
| 'website';
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<n-scrollbar ref="scrollbar" class="h-full" :content-class="routeProps.fullPage ? 'h-full' : ''">
|
||||
<div class="inline-block wh-full bg-[#f6f9f8]">
|
||||
<div class="inline-block wh-full bg-[#f6f9f8] dark:bg-dark">
|
||||
<router-view v-slot="{ Component, route: itemRoute }">
|
||||
<transition :name="theme.pageAnimateType" mode="out-in" appear>
|
||||
<keep-alive :include="cacheRoutes">
|
||||
|
@ -258,6 +258,14 @@ const routeConstMap = new Map<RouteKey, RouteConst>([
|
||||
path: '/about',
|
||||
title: '关于'
|
||||
}
|
||||
],
|
||||
[
|
||||
'website',
|
||||
{
|
||||
name: 'website',
|
||||
path: '/website',
|
||||
title: '网址导航'
|
||||
}
|
||||
]
|
||||
]);
|
||||
|
||||
|
27
src/router/modules/website.ts
Normal file
27
src/router/modules/website.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import type { CustomRoute } from '@/interface';
|
||||
import { setSingleRoute } from '@/utils';
|
||||
import { BlankLayout } from '@/layouts';
|
||||
import Website from '@/views/website/index.vue';
|
||||
import { getRouteConst, routeName } from '../constant';
|
||||
|
||||
const { name, path, title } = getRouteConst('website');
|
||||
|
||||
const WEBSITE: CustomRoute = setSingleRoute({
|
||||
route: {
|
||||
name,
|
||||
path,
|
||||
component: Website,
|
||||
meta: {
|
||||
title,
|
||||
icon: 'codicon:remote-explorer',
|
||||
isNotMenu: true
|
||||
}
|
||||
},
|
||||
container: BlankLayout,
|
||||
meta: {
|
||||
order: 8
|
||||
},
|
||||
notFoundName: routeName('not-found')
|
||||
});
|
||||
|
||||
export default WEBSITE;
|
27
src/settings/website.json
Normal file
27
src/settings/website.json
Normal file
@ -0,0 +1,27 @@
|
||||
[
|
||||
{
|
||||
"title": "编程",
|
||||
"children": [
|
||||
{
|
||||
"title": "网站论坛",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"title": "前端",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"title": "设计",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"title": "工具",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"title": "文档",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
7
src/settings/website.ts
Normal file
7
src/settings/website.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import type { WebsiteCategory } from '@/interface';
|
||||
|
||||
import websiteJson from './website.json';
|
||||
|
||||
const website: WebsiteCategory[] = websiteJson;
|
||||
|
||||
export default website;
|
22
src/views/website/index.vue
Normal file
22
src/views/website/index.vue
Normal file
@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div>
|
||||
<header class="flex-y-center justify-between h-78px px-24px bg-light dark:bg-dark shadow-sm">
|
||||
<div class="flex-y-center">
|
||||
<system-logo class="w-48px h-48px mr-12px" :color="theme.themeColor" />
|
||||
<n-gradient-text size="32">Soybean 网址导航</n-gradient-text>
|
||||
</div>
|
||||
<theme-switch :dark="theme.darkMode" @update="handleDarkMode" />
|
||||
</header>
|
||||
<n-space :vertical="true"></n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NSpace, NGradientText } from 'naive-ui';
|
||||
import { SystemLogo, ThemeSwitch } from '@/components';
|
||||
import { useThemeStore } from '@/store';
|
||||
|
||||
const theme = useThemeStore();
|
||||
const { handleDarkMode } = useThemeStore();
|
||||
</script>
|
||||
<style scoped></style>
|
Loading…
Reference in New Issue
Block a user