chore: 完成归档页面开发

This commit is contained in:
pengzhanbo 2022-04-06 05:45:20 +08:00
parent 820f2f91dd
commit f4077dc492
19 changed files with 220 additions and 62 deletions

View File

@ -5,3 +5,4 @@ dist/
!.vuepress/
!.*.js
scripts/
LICENSE

View File

@ -11,7 +11,7 @@ export default defineUserConfig<PlumeThemeOptions>({
themeConfig: {
logo: 'https://pengzhanbo.cn/g.gif',
avatar: {
url: 'https://via.placeholder.com/300?text=Profile+Photo',
url: '/images/blogger.jpg',
name: 'Plume Theme',
description: 'The Theme for Vuepress 2.0',
},
@ -37,49 +37,25 @@ export default defineUserConfig<PlumeThemeOptions>({
},
darkMode: true,
navbar: [
{ text: '首页', link: '/' },
{
text: '分类',
link: '/category/',
},
{
text: '标签',
link: '/tag/',
},
{
text: '笔记',
children: [
// {
// text: '技术',
// children: [{ text: '《typescript学习笔记》', link: '/' }],
// },
// {
// text: '技术',
// children: [{ text: '《typescript学习笔记》', link: '/' }],
// },
{
text: 'typescript',
link: '/note/typescript/',
},
{
text: '标签',
link: '/tag/',
},
],
},
],
footer: {
copyright: 'Copyright © 2022-present pengzhanbo',
content: '',
},
themePlugins: {
caniuse: {
mode: 'embed',
},
search: {
// hotKeys: ['s', '/'],
// maxSuggestions: 5,
// isSearchable: (page) => page.path !== '/',
// getExtraFields: () => [],
locales: {
'/': {
placeholder: '搜索',

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 KiB

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -1,3 +1,137 @@
<script lang="ts" setup>
import BlogInfo from '@theme-plume/BlogInfo.vue'
import DropdownTransition from '@theme-plume/DropdownTransition.vue'
import { useArchive } from '../composables'
const archiveList = useArchive()
</script>
<template>
<div></div>
<div class="archive-wrapper">
<div class="archive-container">
<DropdownTransition>
<div class="archive-content">
<div
v-for="archive in archiveList"
:key="archive.year"
class="archive-items"
>
<h2>{{ archive.year }}</h2>
<ul class="archive-list">
<li v-for="child in archive.children" :key="child.link">
<span>{{ child.date }}</span>
<RouterLink :to="child.link">{{ child.text }}</RouterLink>
</li>
</ul>
</div>
</div>
</DropdownTransition>
<BlogInfo></BlogInfo>
</div>
</div>
</template>
<style lang="scss">
@import '../styles/_mixins';
.archive-wrapper {
@include wrapper;
.archive-container {
@include container_wrapper;
display: flex;
align-items: flex-start;
padding: 1.25rem 0;
}
.archive-content {
flex: 1;
}
.archive-items {
h2 {
position: relative;
margin: 0 0 0 4rem;
border-left: solid 4px var(--c-border);
border-bottom: none;
padding: 1.25rem;
&::before {
content: '';
display: inline-block;
width: 12px;
height: 12px;
background-color: var(--c-bg-container);
border-radius: 6px;
border: solid 2px var(--c-border-dark);
position: absolute;
top: 50%;
left: -2px;
transform: translate(-50%, -50%);
}
}
}
.archive-list {
list-style: none;
padding-left: 0;
margin: 0;
li {
position: relative;
margin-left: 4rem;
border-left: solid 4px var(--c-border);
padding: 1.25rem;
&::before {
content: '';
display: inline-block;
width: 10px;
height: 10px;
background-color: var(--c-bg-container);
border-radius: 5px;
border: solid 2px var(--c-border-dark);
position: absolute;
top: 50%;
left: -2px;
transform: translate(-50%, -50%);
transition: border-color var(--t-color);
}
> span {
position: absolute;
left: -1.25rem;
top: 50%;
transform: translate(-100%, -50%);
color: var(--c-text-light);
font-size: 14px;
transition: color var(--t-color);
}
> a {
display: inline-block;
width: 100%;
padding: 0.5rem 1.25rem;
background-color: var(--c-bg-container);
border-radius: var(--p-around);
box-shadow: var(--shadow-sm);
color: var(--c-text);
transition: color var(--t-color), box-shadow var(--t-color);
}
&:hover {
> span,
> a {
color: var(--c-text-accent);
}
> a {
box-shadow: var(--shadow);
}
&::before {
border-color: var(--c-text-accent);
}
}
}
}
}
</style>

View File

@ -1,40 +1,15 @@
<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue'
import { onBeforeRouteUpdate, useRouter } from 'vue-router'
import { computed } from 'vue'
import { useThemeLocaleData } from '../composables'
const themeLocale = useThemeLocaleData()
const router = useRouter()
const footer = computed(() => {
return themeLocale.value.footer
})
const style = ref({})
function setStyle(): void {
if (__VUEPRESS_SSR__) return
setTimeout(() => {
if (
document.documentElement.scrollHeight <=
document.documentElement.clientHeight
) {
style.value = {
position: 'fixed',
bottom: 0,
left: 0,
}
} else {
style.value = {}
}
}, 30)
}
router.beforeEach(() => {
setStyle()
})
onMounted(() => setStyle())
onBeforeRouteUpdate(() => setStyle())
</script>
<template>
<footer v-if="footer" class="theme-plume-footer" :style="style">
<footer v-if="footer" class="theme-plume-footer">
<!-- eslint-disable vue/no-v-html -->
<div
v-if="footer.content"
@ -50,12 +25,14 @@ onBeforeRouteUpdate(() => setStyle())
</template>
<style lang="scss">
.theme-plume-footer {
width: 100%;
padding: 1.25rem;
margin-top: 4rem;
position: absolute;
left: 0;
bottom: 0;
display: flex;
justify-content: flex-start;
align-items: flex-start;
width: 100%;
padding: 1.25rem;
background-color: var(--c-bg-container);
box-shadow: var(--shadow-footer);
font-size: 14px;

View File

@ -0,0 +1,38 @@
import { ref } from 'vue'
import type { Ref } from 'vue'
import { usePostAllIndex } from './postIndex'
export interface ArchiveItem {
year: string
children: ArchiveChild[]
}
export interface ArchiveChild {
date: string
text: string
link: string
}
export type ArchiveData = ArchiveItem[]
export type ArchiveListRef = Ref<ArchiveData>
export const useArchive = (): ArchiveListRef => {
const archiveList: ArchiveData = []
const postList = usePostAllIndex().value
postList.forEach((post) => {
const [year, month, day] = post.createTime.split('-')
let current = archiveList.find((arch) => arch.year === year)
if (!current) {
current = { year, children: [] }
archiveList.push(current)
}
current.children.push({
date: `${month}-${day}`,
text: post.title,
link: post.path,
})
})
return ref(archiveList)
}

View File

@ -10,3 +10,4 @@ export * from './scrollPromise'
export * from './tag'
export * from './category'
export * from './archive'

View File

@ -3,7 +3,12 @@ import { isLinkHttp, isString } from '@vuepress/shared'
import type { ComputedRef } from 'vue'
import { computed } from 'vue'
import { useRouter } from 'vue-router'
import type { NavbarGroup, NavbarItem, ResolveNavbarItem } from '../../shared'
import type {
NavbarGroup,
NavbarItem,
NavLink,
ResolveNavbarItem,
} from '../../shared'
import { resolveRepoType } from '../utils'
import { useNavLink } from './navLink'
import { useThemeLocaleData } from './themeData'
@ -49,7 +54,7 @@ export const useNavbarSelectLanguage = (): ComputedRef<ResolveNavbarItem[]> => {
) {
link = targetLocalePage
} else {
link = targetThemeLocale.home ?? targetLocalPath
link = (targetThemeLocale.home as NavLink)?.link ?? targetLocalPath
}
}
return { text, link }
@ -111,5 +116,13 @@ const resolveNavbarItem = (
export const useNavbarConfig = (): ComputedRef<ResolveNavbarItem[]> => {
const themeLocale = useThemeLocaleData()
return computed(() => (themeLocale.value.navbar || []).map(resolveNavbarItem))
const { navbar, home, category, archive, tag } = themeLocale.value
const config: NavbarItem[] = [
home as NavbarItem,
...((navbar || []) as unknown as NavbarItem[]),
category as NavbarItem,
tag as NavbarItem,
archive as NavbarItem,
].filter((nav) => nav)
return computed(() => config.map(resolveNavbarItem))
}

View File

@ -9,9 +9,11 @@ import Tag from '@theme-plume/Tag.vue'
import { usePageFrontmatter } from '@vuepress/client'
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { useThemeLocaleData } from '../composables'
const route = useRoute()
const frontmatter = usePageFrontmatter()
const themeLocale = useThemeLocaleData()
const isHome = computed(() => {
return route.path === '/' && frontmatter.value.home
})
@ -20,6 +22,10 @@ const pageType = computed(() => {
return (frontmatter.value.pageType as string) || ''
})
const footer = computed(() => {
return themeLocale.value.footer
})
const pageMap = {
category: Category,
archive: Archive,
@ -27,7 +33,7 @@ const pageMap = {
}
</script>
<template>
<div class="plume-theme">
<div class="plume-theme" :class="footer ? 'bottom' : ''">
<slot name="navbar">
<Navbar>
<template #before>

View File

@ -6,5 +6,6 @@
@use 'transition';
@use 'icons';
@use 'layout';
@use 'code';
@use 'toc';

View File

@ -0,0 +1,9 @@
.plume-theme {
position: relative;
min-height: 100vh;
padding-bottom: 2rem;
&.bottom {
padding-bottom: 6rem;
}
}

View File

@ -1,8 +1,10 @@
import type { PlumeThemeLocaleOptions } from '../shared'
export const defaultLocaleOption: Partial<PlumeThemeLocaleOptions> = {
home: { text: '首页', link: '/' },
article: '/article',
tag: { text: '标签', link: '/tag' },
category: { text: '分类', link: '/category' },
notes: { link: '/note', dir: 'notes', notes: [] },
archive: { link: '/timeline', text: '归档' },
}

View File

@ -56,7 +56,7 @@ export interface PlumeThemeLocaleData extends LocaleData {
/**
*
*/
home?: string
home?: false | NavLink
/**
* logo
*/