Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

26 hacxy #29

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/docs/guide/intro/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
sidebar:
order: 10
sort: 1
title: 简介
text: 概述
---
Expand Down
5 changes: 5 additions & 0 deletions packages/docs/guide/layout/blog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
sidebar:
sort: 1
---

# 博客页

待补充
18 changes: 18 additions & 0 deletions packages/docs/guide/layout/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
---
sidebar:
sort: 2
title: 布局
---

# 概述

`Mild Theme` 提供了额外的布局, 用于搭建博客或搭建技术文档站, 不同的布局用于展示不同的内容.

## 默认主题布局:

- `doc`: 默认布局, 它将整个 Markdown 内容设置为“documentation”外观。它的工作原理是将整个内容包装在 css `vp-doc` 类中,并将样式应用于它下面的元素。

- `page` 布局, page 被视为“空白页”。Markdown 仍然会被解析,所有的 Markdown 扩展 都和 doc 布局一样运行,但它没有任何默认样式。

- `home` 布局, 将生成模板化的“主页”。在此布局中,可以设置额外的选项,例如 hero 和 features 以进一步自定义内容。请访问[默认主题](https://vitepress.dev/zh/reference/default-theme-home-page): 主页了解更多详情。

## 博客布局

- `blog` 布局, 将生成模板化的博客页, 在此布局中, 可以快速生成一个文章列表和分页器, 用于展示当前`<root>`下所有的`.md`文件.
![](https://hacxy-1259720482.cos.ap-hongkong.myqcloud.com/images/Kapture%202025-01-13%20at%2014.43.57.gif)

## 标签页布局
14 changes: 13 additions & 1 deletion packages/docs/guide/support/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
---
sidebar:
title: 主题能力
order: 9
sort: 3
---

# 概述

`Mild Theme` 在默认主题的基础之上加入了更加丰富的能力, 例如: 图片预览、文章顶部信息、 自动侧边栏、文章评论等.

目的是为了弥补默认主题缺失的,或者说不太好用的部分, 设计理念是尽可能保留原有配置规则, 在原有属性添加某个类型或者直接新增一个属性来控制这些新的特性.

## 特性

- 自动根据目录结构生成侧边栏
- 支持RSS文章订阅
- 代码分组图标支持
- 页面加载进度条
- 文章评论
28 changes: 26 additions & 2 deletions packages/docs/guide/support/sidebar.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
---
sidebar:
order: 10
sort: 1
---

# 自动侧边栏

自动侧边栏基于[默认主题的侧边栏](https://vitepress.dev/zh/reference/default-theme-sidebar)实现, 可以自动扫描某一个路径下所有`md`文件, 并结合实际目录结构组成一颗路径树, 例如: 希望在文档中创建单独的侧边栏,例如“指南”页面和“配置参考”页面。
## 背景

默认主题的侧边栏已经足够覆盖各种应用场景, 但唯独不支持自动根据目录结构生成侧边栏结构, 虽然可以借助[社区的插件](https://github.com/hacxy/awesome-vitepress?tab=readme-ov-file#community-plugins), 但插件也存在短板, 不能满足我所有的需求:

- 首先是数据结构, 文件目录结构本身是树形结构, 那么在扫描整个目录时, 应该需要覆盖到所有子目录, 并保留这些结构输出最终的 `sidebar` 结构.
- 支持单侧边栏, 同时也支持多侧边栏
- 当frontmatter 的sidebar 属性为false时, 可以隐藏某一个markdwon文件, 或一整个文件夹
- 排序, 可以对分组进行排序, 也可以对每一组下的单个文件进行排序
- 配置简单, 兼容原sidebar配置规则, 并扩展frontmatter
- 热更新, 注重体验, 新增或移除`md`文件时, 实时生成最新的sidebar结构

为了满足上述需求, 我不再使用插件, 而是使用: 构建时数据加载以及sidebar组件改造, 最终效果达到了我的预期, 现在sidebar的配置是更灵活的, 更智能的.

## 使用

自动侧边栏基于[默认主题的侧边栏](https://vitepress.dev/zh/reference/default-theme-sidebar)实现, 可以自动扫描某一个路径下所有`md`文件, 并结合实际目录结构组成一颗路径树, 例如: 希望在文档中创建单独的侧边栏,例如“指南”页面和“配置参考”页面。
为此,首先将你的页面组织到每个所需部分的目录中:

```
Expand Down Expand Up @@ -35,3 +49,13 @@ export default {
}
};
```

## Frontmatter

```md
---
sidebar:
text: 概述
sort: 1
---
```
1 change: 1 addition & 0 deletions packages/theme/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default linter({
'vue/valid-v-slot': 0,
'vue/component-name-in-template-casing': ['error', 'PascalCase'],
'unused-imports/no-unused-vars': ['error', { caughtErrorsIgnorePattern: '^_' }],
'vue/no-v-text-v-html-on-component': 0
},
ignores: [
'packages/demo/**/*',
Expand Down
1 change: 1 addition & 0 deletions packages/theme/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@shikijs/vitepress-twoslash": "^1.24.3",
"@vueuse/core": "^12.0.0",
"@vueuse/motion": "^2.2.6",
"directory-tree": "^3.5.2",
"fs-extra": "^11.2.0",
"gray-matter": "^4.0.3",
"naive-ui": "^2.40.4",
Expand Down
8 changes: 4 additions & 4 deletions packages/theme/src/components/BlogPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { NPagination } from 'naive-ui';
import { useData, useRouter } from 'vitepress';
import { computed, onMounted, ref, watch } from 'vue';
import { DEFAULT_PAGE_SIZE } from '../constants';
import { useArticleData } from '../hooks/useArticleData';
import { data } from '../datas/articles.data';
import { paginate } from '../utils/client/article';
import ArticlesList from './ArticlesList.vue';

Expand All @@ -14,15 +14,15 @@ const articleTitle = ref(frontmatter.value?.article?.title);
const pageSize = ref(frontmatter.value?.article?.pageSize || DEFAULT_PAGE_SIZE);
const params = useUrlSearchParams<{ pageNum: string }>();
const currentPage = ref(1);
const { articleData } = useArticleData();
// const { articleData: data } = useArticleData();

const totalPages = computed(() => {
const total = articleData.value.length || 0;
const total = data.list.length || 0;
return Math.ceil(total / pageSize.value);
});

const posts = computed(() => {
return paginate(articleData.value, pageSize.value, currentPage.value);
return paginate(data.list, pageSize.value, currentPage.value);
});

onMounted(() => {
Expand Down
3 changes: 1 addition & 2 deletions packages/theme/src/components/DocFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useData } from 'vitepress';
import { computed } from 'vue';
import { useEditLink } from '../utils/client/edit-link';
import { usePrevNext } from '../utils/client/prev-next';
import Comment from './Comment.vue';
import VPDocFooterLastUpdated from './DocFooterLastUpdated.vue';
import VPLink from './Link.vue';

Expand Down Expand Up @@ -78,7 +77,7 @@ const showFooter = computed(
</nav>
</footer>

<Comment />
<!-- <Comment /> -->
</template>

<style scoped lang="scss">
Expand Down
2 changes: 1 addition & 1 deletion packages/theme/src/components/Sidebar.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script lang="ts" setup>
import { useScrollLock } from '@vueuse/core';
import { inBrowser } from 'vitepress';
import VPSidebarGroup from 'vitepress/dist/client/theme-default/components/VPSidebarGroup.vue';
import { ref, watch } from 'vue';
import { useSidebar } from '../hooks/useSidebar';
import VPSidebarGroup from './SidebarGroup.vue';

const props = defineProps<{
open: boolean
Expand Down
59 changes: 59 additions & 0 deletions packages/theme/src/components/SidebarGroup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<script setup lang="ts">
import type { DefaultTheme } from 'vitepress/theme';
import { onBeforeUnmount, onMounted, ref } from 'vue';
import VPSidebarItem from './SidebarItem.vue';

defineProps<{
items: (DefaultTheme.SidebarItem & { hide?: boolean })[]
}>();

const disableTransition = ref(true);
let timer: ReturnType<typeof setTimeout> | null = null;

onMounted(() => {
timer = setTimeout(() => {
timer = null;
disableTransition.value = false;
}, 300);
});

onBeforeUnmount(() => {
if (timer !== null) {
clearTimeout(timer);
timer = null;
}
});
</script>

<template>
<template
v-for="item in items"
:key="item.link"
>
<div
v-if="!item.hide"
class="group"
:class="{ 'no-transition': disableTransition }"
>
<VPSidebarItem :item="item" :depth="0" />
</div>
</template>
</template>

<style scoped lang="scss">
.no-transition :deep(.caret-icon) {
transition: none;
}

.group + .group {
border-top: 1px solid var(--vp-c-divider);
padding-top: 10px;
}

@media (min-width: 960px) {
.group {
padding-top: 10px;
width: calc(var(--vp-sidebar-width) - 64px);
}
}
</style>
Loading
Loading