valaxy-theme-hairy 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +21 -21
- package/client/index.ts +1 -1
- package/components/HairyBody.vue +49 -49
- package/components/HairyCodepen.vue +40 -40
- package/components/HairyComment.vue +33 -33
- package/components/HairyContainer.vue +17 -17
- package/components/HairyDrawer.vue +44 -44
- package/components/HairyFooter.vue +62 -62
- package/components/HairyHeader.vue +32 -32
- package/components/HairyImage.vue +15 -15
- package/components/HairyImageGroup.vue +65 -65
- package/components/HairyNavbar.vue +56 -56
- package/components/HairyPageArchives.vue +59 -59
- package/components/HairyPageTags.vue +48 -48
- package/components/HairyPosts.vue +54 -54
- package/components/HairySearch.vue +201 -201
- package/components/HairySidebar.vue +30 -30
- package/components/HairyTabbar.vue +56 -56
- package/components/PageTags.vue +48 -48
- package/components/ValaxyMain.vue +45 -45
- package/components/navbar/HairyNav.vue +16 -16
- package/components/navbar/HairyNavExpand.vue +12 -12
- package/components/navbar/HairyNavItem.vue +35 -35
- package/components/navbar/HairyNavbarBackground.vue +7 -7
- package/components/navbar/HairyNavbarSearch.vue +8 -8
- package/components/navbar/HairyNavbarTitle.vue +15 -15
- package/components/navbar/HairyNavbarToggleDark.vue +22 -22
- package/components/parts/HairyBreadcrumb.vue +51 -51
- package/components/parts/HairyBreadcrumbItem.vue +11 -11
- package/components/parts/HairyFootFish.js +352 -352
- package/components/parts/HairyFootFish.vue +38 -38
- package/components/parts/HairyHeadHero.vue +34 -34
- package/components/parts/HairyHeadWaves.vue +67 -67
- package/components/parts/HairyImageGlobal.vue +51 -51
- package/components/parts/HairyImageViewer.vue +23 -23
- package/components/parts/HairyLink.vue +21 -21
- package/components/parts/HairyMenu.vue +16 -16
- package/components/parts/HairyMenuItem.vue +47 -47
- package/components/parts/HairyOutline.vue +99 -99
- package/components/parts/HairyOutlineItem.vue +48 -48
- package/components/parts/HairySocialLinks.vue +27 -27
- package/components/parts/HairyTimelineContent.vue +39 -39
- package/components/parts/HairyUserNav.vue +95 -95
- package/components/parts/HairyUserStats.vue +18 -18
- package/components/posts/HairyArticleImage.vue +126 -126
- package/components/posts/HairyArticleSeries.vue +89 -89
- package/components/posts/HairyArticleText.vue +43 -43
- package/components/posts/HairyPostFooter.vue +15 -15
- package/components/posts/HairyPostImageList.vue +27 -27
- package/components/posts/HairyPostTextsList.vue +22 -22
- package/components/posts/HairyPostToggleLayout.vue +36 -36
- package/components/third/HairyAlgoliaSearch.vue +17 -17
- package/components/third/HairyFuseSearch.vue +10 -10
- package/components/third/HairyFuseSearchDialog.vue +32 -32
- package/components/third/HairyFuseSearchDropdown.vue +77 -77
- package/components/third/HairyFuseSearchFooter.vue +28 -28
- package/components/third/HairyFuseSearchHeader.vue +30 -30
- package/components/third/HairyFuseSearchHit.vue +52 -52
- package/components/third/HairySearchBtnDisplay.vue +29 -29
- package/components/third/HairySearchBtnInput.vue +20 -20
- package/components/third/HairySearchBtnKeys.vue +19 -19
- package/components/third/HairySwiperCarousel.vue +45 -45
- package/composables/archives.ts +48 -48
- package/composables/category.ts +43 -43
- package/composables/config.ts +11 -11
- package/composables/dark.ts +13 -13
- package/composables/fuse.ts +60 -60
- package/composables/index.ts +7 -7
- package/composables/layout.ts +16 -16
- package/composables/outline.ts +49 -49
- package/composables/tags.ts +36 -36
- package/layouts/archive-month.vue +13 -13
- package/layouts/archive-year.vue +13 -13
- package/layouts/archives.vue +11 -11
- package/layouts/categories.vue +13 -13
- package/layouts/default.vue +13 -15
- package/layouts/home.vue +33 -33
- package/layouts/post.vue +54 -54
- package/layouts/tag.vue +10 -10
- package/layouts/tags.vue +10 -14
- package/library/loading.scss +535 -535
- package/library/loading.ts +60 -60
- package/library/scroll.ts +22 -22
- package/locales/en.yml +1 -1
- package/locales/zh-CN.yml +1 -1
- package/node/images/default.json +139 -139
- package/node/images/index.ts +46 -46
- package/node/images/shims.d.ts +8 -8
- package/node/index.ts +2 -2
- package/node/theme/index.ts +78 -78
- package/package.json +1 -1
- package/pages/archives/[year]/[month]/index.vue +48 -48
- package/pages/archives/[year]/index.vue +73 -73
- package/pages/archives/index.md +6 -0
- package/pages/categories/[...its].vue +108 -108
- package/pages/index.vue +8 -8
- package/pages/page/[page].vue +12 -12
- package/pages/tags/[tag]/index.vue +38 -38
- package/pages/tags/index.md +7 -0
- package/setup/main.ts +9 -9
- package/store/index.ts +1 -1
- package/store/modules/global.ts +12 -12
- package/styles/components/aplayer.scss +75 -75
- package/styles/components/index.scss +3 -3
- package/styles/components/markdown.scss +89 -89
- package/styles/components/nprogress.scss +15 -15
- package/styles/components/scrollbar.scss +25 -25
- package/styles/css-vars.scss +171 -171
- package/styles/element-plus/index.scss +1 -1
- package/styles/element-plus/tabs.scss +25 -25
- package/styles/element-plus/timeline.scss +18 -18
- package/styles/font-face.scss +19 -19
- package/styles/global.scss +38 -38
- package/styles/index.scss +3 -3
- package/tsconfig.json +27 -27
- package/types/index.d.ts +163 -163
- package/unocss.config.ts +43 -43
- package/utils/index.ts +37 -37
- package/valaxy.config.ts +26 -26
- package/pages/archives/index.vue +0 -6
- package/pages/tags/index.vue +0 -6
@@ -1,65 +1,65 @@
|
|
1
|
-
<script lang="ts" setup>
|
2
|
-
import { computed, provide, useCssVars, useSlots } from 'vue'
|
3
|
-
import { renderOverlay } from '@overlastic/vue'
|
4
|
-
import type { ImageViewerProps } from 'element-plus
|
5
|
-
import { atWillToUnit } from '@hairy/utils'
|
6
|
-
import HairyImageViewer from './parts/HairyImageViewer.vue'
|
7
|
-
|
8
|
-
const props = withDefaults(defineProps<{
|
9
|
-
row?: string | number
|
10
|
-
col?: string | number
|
11
|
-
gap?: string | number
|
12
|
-
justify?: string
|
13
|
-
align?: string
|
14
|
-
}>(), {
|
15
|
-
row: 'auto',
|
16
|
-
col: 'auto',
|
17
|
-
gap: 10,
|
18
|
-
justify: 'space-evenly',
|
19
|
-
align: 'initial',
|
20
|
-
})
|
21
|
-
|
22
|
-
useCssVars(() => ({
|
23
|
-
width: atWillToUnit(props.row),
|
24
|
-
height: atWillToUnit(props.col),
|
25
|
-
gap: atWillToUnit(props.gap),
|
26
|
-
justify: props.justify,
|
27
|
-
align: props.align,
|
28
|
-
}))
|
29
|
-
|
30
|
-
const slots = useSlots()
|
31
|
-
const paths = computed(() => slots
|
32
|
-
.default?.()
|
33
|
-
.map(v => v.props?.src)
|
34
|
-
.filter(Boolean) as string[],
|
35
|
-
)
|
36
|
-
|
37
|
-
function preview(url: string) {
|
38
|
-
const initialIndex = paths.value.findIndex(v => v === url) || 0
|
39
|
-
renderOverlay<Partial<ImageViewerProps>>(HairyImageViewer, {
|
40
|
-
urlList: paths.value,
|
41
|
-
initialIndex,
|
42
|
-
})
|
43
|
-
}
|
44
|
-
|
45
|
-
provide('HairyImageGroup:preview', preview)
|
46
|
-
</script>
|
47
|
-
|
48
|
-
<template>
|
49
|
-
<div class="HairyImageGroup">
|
50
|
-
<slot />
|
51
|
-
</div>
|
52
|
-
</template>
|
53
|
-
|
54
|
-
<style lang="scss" scoped>
|
55
|
-
.HairyImageGroup {
|
56
|
-
display: grid;
|
57
|
-
grid-template-columns: repeat(auto-fill, var(--width, auto));
|
58
|
-
gap: var(--gap);
|
59
|
-
justify-content: var(--justify);
|
60
|
-
align-items: var(--align);
|
61
|
-
:deep(.HairyImage) {
|
62
|
-
height: var(--height, auto);
|
63
|
-
}
|
64
|
-
}
|
65
|
-
</style>
|
1
|
+
<script lang="ts" setup>
|
2
|
+
import { computed, provide, useCssVars, useSlots } from 'vue'
|
3
|
+
import { renderOverlay } from '@overlastic/vue'
|
4
|
+
import type { ImageViewerProps } from 'element-plus'
|
5
|
+
import { atWillToUnit } from '@hairy/utils'
|
6
|
+
import HairyImageViewer from './parts/HairyImageViewer.vue'
|
7
|
+
|
8
|
+
const props = withDefaults(defineProps<{
|
9
|
+
row?: string | number
|
10
|
+
col?: string | number
|
11
|
+
gap?: string | number
|
12
|
+
justify?: string
|
13
|
+
align?: string
|
14
|
+
}>(), {
|
15
|
+
row: 'auto',
|
16
|
+
col: 'auto',
|
17
|
+
gap: 10,
|
18
|
+
justify: 'space-evenly',
|
19
|
+
align: 'initial',
|
20
|
+
})
|
21
|
+
|
22
|
+
useCssVars(() => ({
|
23
|
+
width: atWillToUnit(props.row),
|
24
|
+
height: atWillToUnit(props.col),
|
25
|
+
gap: atWillToUnit(props.gap),
|
26
|
+
justify: props.justify,
|
27
|
+
align: props.align,
|
28
|
+
}))
|
29
|
+
|
30
|
+
const slots = useSlots()
|
31
|
+
const paths = computed(() => slots
|
32
|
+
.default?.()
|
33
|
+
.map(v => v.props?.src)
|
34
|
+
.filter(Boolean) as string[],
|
35
|
+
)
|
36
|
+
|
37
|
+
function preview(url: string) {
|
38
|
+
const initialIndex = paths.value.findIndex(v => v === url) || 0
|
39
|
+
renderOverlay<Partial<ImageViewerProps>>(HairyImageViewer, {
|
40
|
+
urlList: paths.value,
|
41
|
+
initialIndex,
|
42
|
+
})
|
43
|
+
}
|
44
|
+
|
45
|
+
provide('HairyImageGroup:preview', preview)
|
46
|
+
</script>
|
47
|
+
|
48
|
+
<template>
|
49
|
+
<div class="HairyImageGroup">
|
50
|
+
<slot />
|
51
|
+
</div>
|
52
|
+
</template>
|
53
|
+
|
54
|
+
<style lang="scss" scoped>
|
55
|
+
.HairyImageGroup {
|
56
|
+
display: grid;
|
57
|
+
grid-template-columns: repeat(auto-fill, var(--width, auto));
|
58
|
+
gap: var(--gap);
|
59
|
+
justify-content: var(--justify);
|
60
|
+
align-items: var(--align);
|
61
|
+
:deep(.HairyImage) {
|
62
|
+
height: var(--height, auto);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
</style>
|
@@ -1,56 +1,56 @@
|
|
1
|
-
<script lang="ts" setup>
|
2
|
-
import { storeToRefs } from 'pinia'
|
3
|
-
import { computed, onMounted, ref } from 'vue'
|
4
|
-
import { useElementSize, useScroll, whenever } from '@vueuse/core'
|
5
|
-
import { useSiteConfig } from 'valaxy'
|
6
|
-
import { useGlobalStore } from '../store'
|
7
|
-
|
8
|
-
// get header height
|
9
|
-
const globalStore = useGlobalStore()
|
10
|
-
const { headerRef } = storeToRefs(globalStore)
|
11
|
-
const headerSize = useElementSize(headerRef)
|
12
|
-
const headerHeight = computed(() => headerSize.height.value)
|
13
|
-
|
14
|
-
// get document scroll
|
15
|
-
const documentRef = ref()
|
16
|
-
const scroll = useScroll(documentRef)
|
17
|
-
const dire = ref<'top' | 'bottom'>('top')
|
18
|
-
|
19
|
-
whenever(() => scroll.directions.top, () => dire.value = 'top')
|
20
|
-
whenever(() => scroll.directions.bottom, () => dire.value = 'bottom')
|
21
|
-
|
22
|
-
const show = computed(() => {
|
23
|
-
return scroll.y.value < (headerHeight.value / 2)
|
24
|
-
|| dire.value === 'top'
|
25
|
-
})
|
26
|
-
const config = useSiteConfig()
|
27
|
-
onMounted(() => documentRef.value = document)
|
28
|
-
</script>
|
29
|
-
|
30
|
-
<template>
|
31
|
-
<div
|
32
|
-
class="fixed w-full h-3.125rem lt-sm:h-3.5rem top-0 opacity-0 z-10000"
|
33
|
-
:class="[show && 'opacity-100']"
|
34
|
-
>
|
35
|
-
<div class="px-12px md:px-0 mx-auto container flex relative z-1 h-full">
|
36
|
-
<div class="flex items-center lt-sm:order-1 lt-sm:flex-1 justify-center">
|
37
|
-
<HairyLink class="px-2.5" type="white" :href="config.url">
|
38
|
-
{{ config.title }}
|
39
|
-
</HairyLink>
|
40
|
-
</div>
|
41
|
-
<div class="flex items-center sm:flex-1">
|
42
|
-
<HairyNavExpand class="sm:hidden pl-2 pr-13" />
|
43
|
-
<HairyNav class="lt-sm:hidden" />
|
44
|
-
<slot name="nav" />
|
45
|
-
</div>
|
46
|
-
<div class="flex-center order-1">
|
47
|
-
<HairyNavbarToggleDark />
|
48
|
-
<HairySearch />
|
49
|
-
</div>
|
50
|
-
</div>
|
51
|
-
|
52
|
-
<HairyNavbarBackground />
|
53
|
-
</div>
|
54
|
-
</template>
|
55
|
-
|
56
|
-
<style lang="scss" scoped></style>
|
1
|
+
<script lang="ts" setup>
|
2
|
+
import { storeToRefs } from 'pinia'
|
3
|
+
import { computed, onMounted, ref } from 'vue'
|
4
|
+
import { useElementSize, useScroll, whenever } from '@vueuse/core'
|
5
|
+
import { useSiteConfig } from 'valaxy'
|
6
|
+
import { useGlobalStore } from '../store'
|
7
|
+
|
8
|
+
// get header height
|
9
|
+
const globalStore = useGlobalStore()
|
10
|
+
const { headerRef } = storeToRefs(globalStore)
|
11
|
+
const headerSize = useElementSize(headerRef)
|
12
|
+
const headerHeight = computed(() => headerSize.height.value)
|
13
|
+
|
14
|
+
// get document scroll
|
15
|
+
const documentRef = ref()
|
16
|
+
const scroll = useScroll(documentRef)
|
17
|
+
const dire = ref<'top' | 'bottom'>('top')
|
18
|
+
|
19
|
+
whenever(() => scroll.directions.top, () => dire.value = 'top')
|
20
|
+
whenever(() => scroll.directions.bottom, () => dire.value = 'bottom')
|
21
|
+
|
22
|
+
const show = computed(() => {
|
23
|
+
return scroll.y.value < (headerHeight.value / 2)
|
24
|
+
|| dire.value === 'top'
|
25
|
+
})
|
26
|
+
const config = useSiteConfig()
|
27
|
+
onMounted(() => documentRef.value = document)
|
28
|
+
</script>
|
29
|
+
|
30
|
+
<template>
|
31
|
+
<div
|
32
|
+
class="fixed w-full h-3.125rem lt-sm:h-3.5rem top-0 opacity-0 z-10000"
|
33
|
+
:class="[show && 'opacity-100']"
|
34
|
+
>
|
35
|
+
<div class="px-12px md:px-0 mx-auto container flex relative z-1 h-full">
|
36
|
+
<div class="flex items-center lt-sm:order-1 lt-sm:flex-1 justify-center">
|
37
|
+
<HairyLink class="px-2.5" type="white" :href="config.url">
|
38
|
+
{{ config.title }}
|
39
|
+
</HairyLink>
|
40
|
+
</div>
|
41
|
+
<div class="flex items-center sm:flex-1">
|
42
|
+
<HairyNavExpand class="sm:hidden pl-2 pr-13" />
|
43
|
+
<HairyNav class="lt-sm:hidden" />
|
44
|
+
<slot name="nav" />
|
45
|
+
</div>
|
46
|
+
<div class="flex-center order-1">
|
47
|
+
<HairyNavbarToggleDark />
|
48
|
+
<HairySearch />
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
|
52
|
+
<HairyNavbarBackground />
|
53
|
+
</div>
|
54
|
+
</template>
|
55
|
+
|
56
|
+
<style lang="scss" scoped></style>
|
@@ -1,59 +1,59 @@
|
|
1
|
-
<script lang="ts" setup>
|
2
|
-
import { ElTimeline, ElTimelineItem } from 'element-plus
|
3
|
-
import { usePostList } from 'valaxy'
|
4
|
-
|
5
|
-
import { getArchiveLink } from '../utils'
|
6
|
-
import { useYearArchives } from '../composables'
|
7
|
-
|
8
|
-
const activities = useYearArchives()
|
9
|
-
const posts = usePostList()
|
10
|
-
</script>
|
11
|
-
|
12
|
-
<template>
|
13
|
-
<HairyBreadcrumb class="mb-5" size="large" after="归档">
|
14
|
-
<HairyBreadcrumbItem to="/">
|
15
|
-
首页
|
16
|
-
</HairyBreadcrumbItem>
|
17
|
-
<HairyBreadcrumbItem>
|
18
|
-
目前共计 {{ posts.length }} 篇文章
|
19
|
-
</HairyBreadcrumbItem>
|
20
|
-
</HairyBreadcrumb>
|
21
|
-
<ElTimeline>
|
22
|
-
<ElTimelineItem
|
23
|
-
v-for="(activity, index) in activities"
|
24
|
-
:key="index"
|
25
|
-
size="large"
|
26
|
-
hollow
|
27
|
-
>
|
28
|
-
<div class="activity inline-flex items-center">
|
29
|
-
<HairyLink class="text-size-8" @click="$router.push(getArchiveLink(activity.year))">
|
30
|
-
{{ activity.year }}
|
31
|
-
</HairyLink>
|
32
|
-
<span class="text-gray-5 mx-2">/</span>
|
33
|
-
<HairyLink class="text-size-8" @click="$router.push(getArchiveLink(activity.year, activity.month))">
|
34
|
-
{{ activity.month }}
|
35
|
-
</HairyLink>
|
36
|
-
<span class="text-gray-5 text-size-5 ml-1">({{ activity.count }}篇)</span>
|
37
|
-
</div>
|
38
|
-
<HairyTimelineContent v-for="(item, index) in activity.posts.slice(0, 2)" :key="index" :post="item" />
|
39
|
-
<div v-if="activity.posts.length > 2">
|
40
|
-
<HairyLink @click="$router.push(getArchiveLink(activity.year))">
|
41
|
-
....
|
42
|
-
</HairyLink>
|
43
|
-
</div>
|
44
|
-
</ElTimelineItem>
|
45
|
-
</ElTimeline>
|
46
|
-
</template>
|
47
|
-
|
48
|
-
<route lang="yaml">
|
49
|
-
meta:
|
50
|
-
layout: archive
|
51
|
-
</route>
|
52
|
-
|
53
|
-
<style lang="scss" scoped>
|
54
|
-
.activity:hover {
|
55
|
-
.HairyLink {
|
56
|
-
color: var(--hy-c-primary);
|
57
|
-
}
|
58
|
-
}
|
59
|
-
</style>
|
1
|
+
<script lang="ts" setup>
|
2
|
+
import { ElTimeline, ElTimelineItem } from 'element-plus'
|
3
|
+
import { usePostList } from 'valaxy'
|
4
|
+
|
5
|
+
import { getArchiveLink } from '../utils'
|
6
|
+
import { useYearArchives } from '../composables'
|
7
|
+
|
8
|
+
const activities = useYearArchives()
|
9
|
+
const posts = usePostList()
|
10
|
+
</script>
|
11
|
+
|
12
|
+
<template>
|
13
|
+
<HairyBreadcrumb class="mb-5" size="large" after="归档">
|
14
|
+
<HairyBreadcrumbItem to="/">
|
15
|
+
首页
|
16
|
+
</HairyBreadcrumbItem>
|
17
|
+
<HairyBreadcrumbItem>
|
18
|
+
目前共计 {{ posts.length }} 篇文章
|
19
|
+
</HairyBreadcrumbItem>
|
20
|
+
</HairyBreadcrumb>
|
21
|
+
<ElTimeline>
|
22
|
+
<ElTimelineItem
|
23
|
+
v-for="(activity, index) in activities"
|
24
|
+
:key="index"
|
25
|
+
size="large"
|
26
|
+
hollow
|
27
|
+
>
|
28
|
+
<div class="activity inline-flex items-center">
|
29
|
+
<HairyLink class="text-size-8" @click="$router.push(getArchiveLink(activity.year))">
|
30
|
+
{{ activity.year }}
|
31
|
+
</HairyLink>
|
32
|
+
<span class="text-gray-5 mx-2">/</span>
|
33
|
+
<HairyLink class="text-size-8" @click="$router.push(getArchiveLink(activity.year, activity.month))">
|
34
|
+
{{ activity.month }}
|
35
|
+
</HairyLink>
|
36
|
+
<span class="text-gray-5 text-size-5 ml-1">({{ activity.count }}篇)</span>
|
37
|
+
</div>
|
38
|
+
<HairyTimelineContent v-for="(item, index) in activity.posts.slice(0, 2)" :key="index" :post="item" />
|
39
|
+
<div v-if="activity.posts.length > 2">
|
40
|
+
<HairyLink @click="$router.push(getArchiveLink(activity.year))">
|
41
|
+
....
|
42
|
+
</HairyLink>
|
43
|
+
</div>
|
44
|
+
</ElTimelineItem>
|
45
|
+
</ElTimeline>
|
46
|
+
</template>
|
47
|
+
|
48
|
+
<route lang="yaml">
|
49
|
+
meta:
|
50
|
+
layout: archive
|
51
|
+
</route>
|
52
|
+
|
53
|
+
<style lang="scss" scoped>
|
54
|
+
.activity:hover {
|
55
|
+
.HairyLink {
|
56
|
+
color: var(--hy-c-primary);
|
57
|
+
}
|
58
|
+
}
|
59
|
+
</style>
|
@@ -1,48 +1,48 @@
|
|
1
|
-
<script lang="ts" setup>
|
2
|
-
import { useRouter } from 'vue-router'
|
3
|
-
import { useHairyTags } from '../composables'
|
4
|
-
|
5
|
-
const router = useRouter()
|
6
|
-
|
7
|
-
const { getTagStyle, tags } = useHairyTags({
|
8
|
-
primary: '#1bc9a6',
|
9
|
-
})
|
10
|
-
|
11
|
-
function displayTag(tag: string) {
|
12
|
-
router.push(`/tags/${tag}`)
|
13
|
-
}
|
14
|
-
</script>
|
15
|
-
|
16
|
-
<template>
|
17
|
-
<div class="min-h-59vh flex-center flex-col">
|
18
|
-
<div text="center" class="text-size-2.5em pt-10 mb-5">
|
19
|
-
目前共计 {{ Array.from(tags).length }} 个标签
|
20
|
-
</div>
|
21
|
-
<div text="center" class="max-w-7xl flex flex-wrap justify-center items-center gap-2">
|
22
|
-
<a
|
23
|
-
v-for="[key, tag] in Array.from(tags).sort()"
|
24
|
-
:key="key" class="post-tag cursor-pointer"
|
25
|
-
:style="getTagStyle(tag.count)"
|
26
|
-
p="1"
|
27
|
-
@click="displayTag(key.toString())"
|
28
|
-
>
|
29
|
-
{{ key }}
|
30
|
-
</a>
|
31
|
-
</div>
|
32
|
-
</div>
|
33
|
-
</template>
|
34
|
-
|
35
|
-
<route lang="yaml">
|
36
|
-
meta:
|
37
|
-
layout: tags
|
38
|
-
</route>
|
39
|
-
|
40
|
-
<style lang="scss" scoped>
|
41
|
-
a {
|
42
|
-
color: var(--yun-tag-color);
|
43
|
-
&:hover {
|
44
|
-
--un-text-opacity: 1;
|
45
|
-
color: var(--hy-c-primary-dark);
|
46
|
-
}
|
47
|
-
}
|
48
|
-
</style>
|
1
|
+
<script lang="ts" setup>
|
2
|
+
import { useRouter } from 'vue-router'
|
3
|
+
import { useHairyTags } from '../composables'
|
4
|
+
|
5
|
+
const router = useRouter()
|
6
|
+
|
7
|
+
const { getTagStyle, tags } = useHairyTags({
|
8
|
+
primary: '#1bc9a6',
|
9
|
+
})
|
10
|
+
|
11
|
+
function displayTag(tag: string) {
|
12
|
+
router.push(`/tags/${tag}`)
|
13
|
+
}
|
14
|
+
</script>
|
15
|
+
|
16
|
+
<template>
|
17
|
+
<div class="min-h-59vh flex-center flex-col">
|
18
|
+
<div text="center" class="text-size-2.5em pt-10 mb-5">
|
19
|
+
目前共计 {{ Array.from(tags).length }} 个标签
|
20
|
+
</div>
|
21
|
+
<div text="center" class="max-w-7xl flex flex-wrap justify-center items-center gap-2">
|
22
|
+
<a
|
23
|
+
v-for="[key, tag] in Array.from(tags).sort()"
|
24
|
+
:key="key" class="post-tag cursor-pointer"
|
25
|
+
:style="getTagStyle(tag.count)"
|
26
|
+
p="1"
|
27
|
+
@click="displayTag(key.toString())"
|
28
|
+
>
|
29
|
+
{{ key }}
|
30
|
+
</a>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
</template>
|
34
|
+
|
35
|
+
<route lang="yaml">
|
36
|
+
meta:
|
37
|
+
layout: tags
|
38
|
+
</route>
|
39
|
+
|
40
|
+
<style lang="scss" scoped>
|
41
|
+
a {
|
42
|
+
color: var(--yun-tag-color);
|
43
|
+
&:hover {
|
44
|
+
--un-text-opacity: 1;
|
45
|
+
color: var(--hy-c-primary-dark);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
</style>
|
@@ -1,54 +1,54 @@
|
|
1
|
-
<script lang="ts" setup>
|
2
|
-
import { computed, defineProps, ref, withDefaults } from 'vue'
|
3
|
-
import type { Post } from 'valaxy'
|
4
|
-
import { usePostList } from 'valaxy'
|
5
|
-
import { useLayoutPost } from '../composables'
|
6
|
-
|
7
|
-
const props = withDefaults(defineProps<{
|
8
|
-
type?: string
|
9
|
-
posts?: Post[]
|
10
|
-
curPage?: number
|
11
|
-
pagination?: boolean
|
12
|
-
}>(), {
|
13
|
-
curPage: 1,
|
14
|
-
pagination: false,
|
15
|
-
})
|
16
|
-
const layout = useLayoutPost()
|
17
|
-
|
18
|
-
const pageSize = ref(7)
|
19
|
-
const routes = usePostList({ type: props.type || '' })
|
20
|
-
const posts = computed<any[]>(() => props.posts || routes.value)
|
21
|
-
const pagePosts = computed(() => posts.value.slice((props.curPage - 1) * pageSize.value, props.curPage * pageSize.value))
|
22
|
-
const displayedPosts = computed(() => props.pagination ? pagePosts.value : posts.value)
|
23
|
-
</script>
|
24
|
-
|
25
|
-
<template>
|
26
|
-
<div class="mt-8">
|
27
|
-
<HairyPostToggleLayout />
|
28
|
-
<HairyPostImageList v-if="layout.includes('image')" :posts="displayedPosts" />
|
29
|
-
<HairyPostTextsList v-else :posts="displayedPosts" />
|
30
|
-
<ValaxyPagination v-if="pagination" class="mb-6" :cur-page="curPage" :page-size="pageSize" :total="posts.length" />
|
31
|
-
</div>
|
32
|
-
</template>
|
33
|
-
|
34
|
-
<style lang="scss">
|
35
|
-
.pagination {
|
36
|
-
font-size: 16px;
|
37
|
-
}
|
38
|
-
|
39
|
-
.pagination .prev.active,
|
40
|
-
.pagination .next.active,
|
41
|
-
.pagination .page-number.active {
|
42
|
-
font-weight: normal;
|
43
|
-
background: transparent;
|
44
|
-
color: var(--hy-c-primary);
|
45
|
-
cursor: default;
|
46
|
-
}
|
47
|
-
|
48
|
-
.pagination .prev:hover,
|
49
|
-
.pagination .next:hover,
|
50
|
-
.pagination .page-number:hover {
|
51
|
-
color: var(--va-c-bg);
|
52
|
-
background: rgba(143, 230, 213, 0.8);
|
53
|
-
}
|
54
|
-
</style>
|
1
|
+
<script lang="ts" setup>
|
2
|
+
import { computed, defineProps, ref, withDefaults } from 'vue'
|
3
|
+
import type { Post } from 'valaxy'
|
4
|
+
import { usePostList } from 'valaxy'
|
5
|
+
import { useLayoutPost } from '../composables'
|
6
|
+
|
7
|
+
const props = withDefaults(defineProps<{
|
8
|
+
type?: string
|
9
|
+
posts?: Post[]
|
10
|
+
curPage?: number
|
11
|
+
pagination?: boolean
|
12
|
+
}>(), {
|
13
|
+
curPage: 1,
|
14
|
+
pagination: false,
|
15
|
+
})
|
16
|
+
const layout = useLayoutPost()
|
17
|
+
|
18
|
+
const pageSize = ref(7)
|
19
|
+
const routes = usePostList({ type: props.type || '' })
|
20
|
+
const posts = computed<any[]>(() => props.posts || routes.value)
|
21
|
+
const pagePosts = computed(() => posts.value.slice((props.curPage - 1) * pageSize.value, props.curPage * pageSize.value))
|
22
|
+
const displayedPosts = computed(() => props.pagination ? pagePosts.value : posts.value)
|
23
|
+
</script>
|
24
|
+
|
25
|
+
<template>
|
26
|
+
<div class="mt-8">
|
27
|
+
<HairyPostToggleLayout />
|
28
|
+
<HairyPostImageList v-if="layout.includes('image')" :posts="displayedPosts" />
|
29
|
+
<HairyPostTextsList v-else :posts="displayedPosts" />
|
30
|
+
<ValaxyPagination v-if="pagination" class="mb-6" :cur-page="curPage" :page-size="pageSize" :total="posts.length" />
|
31
|
+
</div>
|
32
|
+
</template>
|
33
|
+
|
34
|
+
<style lang="scss">
|
35
|
+
.pagination {
|
36
|
+
font-size: 16px;
|
37
|
+
}
|
38
|
+
|
39
|
+
.pagination .prev.active,
|
40
|
+
.pagination .next.active,
|
41
|
+
.pagination .page-number.active {
|
42
|
+
font-weight: normal;
|
43
|
+
background: transparent;
|
44
|
+
color: var(--hy-c-primary);
|
45
|
+
cursor: default;
|
46
|
+
}
|
47
|
+
|
48
|
+
.pagination .prev:hover,
|
49
|
+
.pagination .next:hover,
|
50
|
+
.pagination .page-number:hover {
|
51
|
+
color: var(--va-c-bg);
|
52
|
+
background: rgba(143, 230, 213, 0.8);
|
53
|
+
}
|
54
|
+
</style>
|