mirror of
https://github.com/sendevia/website.git
synced 2026-03-05 23:32:45 +08:00
初始化全部文章/搜索文章页面
This commit is contained in:
@@ -21,12 +21,14 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { useData } from "vitepress";
|
||||
|
||||
const { theme, page } = useData();
|
||||
import { useGlobalData } from "../composables/useGlobalData";
|
||||
const { page } = useGlobalData();
|
||||
|
||||
const navItems = computed(() => [
|
||||
{ text: "首页", icon: "home", link: "/" },
|
||||
{ text: "所有文章", icon: "list", link: "/posts" },
|
||||
{ text: "搜索文章", icon: "search", link: "/search.html" },
|
||||
{ text: "Markdown 示例", icon: "counter_1", link: "/posts/markdown-examples" },
|
||||
{ text: "API 示例", icon: "counter_2", link: "/posts/api-examples" },
|
||||
]);
|
||||
|
||||
28
.vitepress/theme/composables/useAllPosts.ts
Normal file
28
.vitepress/theme/composables/useAllPosts.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { ref, onMounted } from "vue";
|
||||
|
||||
export interface PostItem {
|
||||
url: string;
|
||||
title: string;
|
||||
date?: string;
|
||||
content?: string;
|
||||
}
|
||||
|
||||
export function useAllPosts(withContent = false) {
|
||||
const posts = ref<PostItem[]>([]);
|
||||
onMounted(async () => {
|
||||
// @ts-ignore
|
||||
const modules = import.meta.glob("../../../posts/*.md", { eager: true });
|
||||
posts.value = Object.entries(modules)
|
||||
.map(([path, mod]: any) => {
|
||||
const fm = mod?.frontmatter || {};
|
||||
return {
|
||||
url: "/posts/" + path.split("/").pop().replace(/\.md$/, ".html"),
|
||||
title: fm.title || mod.title || path.split("/").pop().replace(/\.md$/, ""),
|
||||
date: fm.date || "",
|
||||
content: withContent ? mod?.default?.toString() || "" : undefined,
|
||||
};
|
||||
})
|
||||
.sort((a, b) => (b.date || "").localeCompare(a.date || ""));
|
||||
});
|
||||
return posts;
|
||||
}
|
||||
6
.vitepress/theme/composables/useGlobalData.ts
Normal file
6
.vitepress/theme/composables/useGlobalData.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { useData } from "vitepress";
|
||||
|
||||
export function useGlobalData() {
|
||||
const { site, page, frontmatter, theme } = useData();
|
||||
return { site, page, frontmatter, theme };
|
||||
}
|
||||
16
.vitepress/theme/layouts/AllPosts.vue
Normal file
16
.vitepress/theme/layouts/AllPosts.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div class="all-posts-page">
|
||||
<h1>所有文章</h1>
|
||||
<ul>
|
||||
<li v-for="post in posts" :key="post.url">
|
||||
<a :href="post.url">{{ post.title }}</a>
|
||||
<span v-if="post.date"> - {{ post.date }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAllPosts } from "../composables/useAllPosts";
|
||||
const posts = useAllPosts();
|
||||
</script>
|
||||
27
.vitepress/theme/layouts/SearchPosts.vue
Normal file
27
.vitepress/theme/layouts/SearchPosts.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div class="search-posts-page">
|
||||
<h1>搜索文章</h1>
|
||||
<input v-model="query" placeholder="输入关键词..." class="search-input" />
|
||||
<ul v-if="filteredPosts.length">
|
||||
<li v-for="post in filteredPosts" :key="post.url">
|
||||
<a :href="post.url">{{ post.title }}</a>
|
||||
<span v-if="post.date"> - {{ post.date }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<p v-else>没有找到相关文章。</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue";
|
||||
import { useAllPosts } from "../composables/useAllPosts";
|
||||
|
||||
const posts = useAllPosts(true);
|
||||
const query = ref("");
|
||||
|
||||
const filteredPosts = computed(() => {
|
||||
if (!query.value) return posts.value;
|
||||
const q = query.value.toLowerCase();
|
||||
return posts.value.filter((post) => post.title.toLowerCase().includes(q) || (post.content && post.content.toLowerCase().includes(q)));
|
||||
});
|
||||
</script>
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#main-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 96px 0px auto;
|
||||
grid-template-columns: 96px auto;
|
||||
|
||||
position: relative;
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
align-items: start;
|
||||
gap: 24px;
|
||||
grid-column: 3;
|
||||
grid-template-columns: repeat(12, minmax(72px, 84px));
|
||||
grid-template-columns: repeat(12, minmax(72px, 100vw));
|
||||
justify-content: center;
|
||||
|
||||
position: relative;
|
||||
|
||||
@@ -34,9 +35,82 @@
|
||||
scrollbar-width: thin;
|
||||
transition: var(--md-sys-motion-duration-medium1) var(--md-sys-motion-easing-emphasized);
|
||||
|
||||
& > {
|
||||
h1 {
|
||||
@include mixin.typescale-style("display-large");
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
grid-column: span 9;
|
||||
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
h6 {
|
||||
grid-column: span 9;
|
||||
}
|
||||
|
||||
img {
|
||||
grid-column: 11 / span 2;
|
||||
grid-row: 2 / span 2;
|
||||
|
||||
margin: auto;
|
||||
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
|
||||
-webkit-mask: var(--via-svg-mask) no-repeat 0 / 100%;
|
||||
mask: var(--via-svg-mask) no-repeat 0 / 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#main-layout-content-filler {
|
||||
display: grid;
|
||||
display: flex;
|
||||
flex-flow: column wrap;
|
||||
grid-column: span 12;
|
||||
|
||||
height: 100%;
|
||||
|
||||
padding: 24px;
|
||||
|
||||
background-color: var(--md-sys-color-surface-container-lowest);
|
||||
|
||||
border-radius: var(--md-sys-shape-corner-extra-extra-large);
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: "";
|
||||
flex-basis: 100%;
|
||||
width: 0;
|
||||
order: 2;
|
||||
}
|
||||
|
||||
div.card[spec="feed"] {
|
||||
width: calc(50% - 12px);
|
||||
|
||||
border-radius: var(--md-sys-shape-corner-extra-large-increased);
|
||||
|
||||
&:nth-child(2n + 4),
|
||||
&[size="large"] {
|
||||
margin-inline-end: 12px;
|
||||
|
||||
order: 1;
|
||||
}
|
||||
|
||||
&:nth-child(2n + 3),
|
||||
&[size="small"] {
|
||||
margin-inline-start: 12px;
|
||||
|
||||
order: 2;
|
||||
}
|
||||
|
||||
& > a {
|
||||
width: 100%;
|
||||
|
||||
color: var(--md-sys-color-on-surface);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#main-layout-scrolltop {
|
||||
@@ -642,92 +716,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&[spec="feed"] {
|
||||
#main-layout-content-flow {
|
||||
gap: 24px;
|
||||
grid-template-rows: minmax(90px, 240px) minmax(180px, 360px) auto;
|
||||
justify-content: center;
|
||||
|
||||
padding-block-end: 68px;
|
||||
|
||||
& > {
|
||||
h1 {
|
||||
@include mixin.typescale-style("display-large");
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
grid-column: span 9;
|
||||
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
h6 {
|
||||
grid-column: span 9;
|
||||
}
|
||||
|
||||
img {
|
||||
grid-column: 11 / span 2;
|
||||
grid-row: 2 / span 2;
|
||||
|
||||
margin: auto;
|
||||
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
|
||||
-webkit-mask: var(--via-svg-mask) no-repeat 0 / 100%;
|
||||
mask: var(--via-svg-mask) no-repeat 0 / 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#main-layout-content-filler {
|
||||
display: flex;
|
||||
flex-flow: column wrap;
|
||||
height: 100%;
|
||||
|
||||
padding: 24px;
|
||||
|
||||
background-color: var(--md-sys-color-surface-container-lowest);
|
||||
|
||||
border-radius: var(--md-sys-shape-corner-extra-extra-large);
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: "";
|
||||
flex-basis: 100%;
|
||||
width: 0;
|
||||
order: 2;
|
||||
}
|
||||
|
||||
div.card[spec="feed"] {
|
||||
width: calc(50% - 12px);
|
||||
|
||||
border-radius: var(--md-sys-shape-corner-extra-large-increased);
|
||||
|
||||
&:nth-child(2n + 4),
|
||||
&[size="large"] {
|
||||
margin-inline-end: 12px;
|
||||
|
||||
order: 1;
|
||||
}
|
||||
|
||||
&:nth-child(2n + 3),
|
||||
&[size="small"] {
|
||||
margin-inline-start: 12px;
|
||||
|
||||
order: 2;
|
||||
}
|
||||
|
||||
& > a {
|
||||
width: 100%;
|
||||
|
||||
color: var(--md-sys-color-on-surface);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1600px) {
|
||||
$columns: 9;
|
||||
|
||||
|
||||
@@ -143,6 +143,8 @@ s {
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 100%;
|
||||
|
||||
border: 1px solid var(--md-sys-color-outline-variant);
|
||||
|
||||
opacity: 0.3;
|
||||
|
||||
Reference in New Issue
Block a user