docs: how to write theme, use api useTags useCategories instead of useTag useCategory

This commit is contained in:
YunYouJun 2023-04-17 01:59:55 +08:00
parent fa9cda035a
commit 903c441f6d
9 changed files with 127 additions and 47 deletions

View File

@ -185,6 +185,74 @@ Markdown 样式是主题呈现文章样式的部分,需要由主题自定义
## 功能
### API
> 你还可以使用 Valaxy 内置的 API 以快速实现相关功能。
#### 获取文章列表
获取文章列表有两种方式。
- `usePostList`: 获取文章列表(不推荐)
```ts
import { usePostList } from 'valaxy'
const postList = usePostList()
```
- `useSiteStore`: 获取全局站点信息(推荐)
```ts
const site = useSiteStore()
// site.postList
```
以上两者之间的区别是,`usePostList` 是一个基础函数,每次调用都会获取所有文章并重新过滤一次,而 `useSiteStore` 则会先调用 `usePostList` 并将获取的文章列表缓存在全局的状态中,以供你后续调用。
(此外,`useSiteStore` 还实现了保存文章时(如标题)热更新列表信息的功能。)
> [valaxy/packages/valaxy-theme-yun/components/YunPostList.vue](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-yun/components/YunPostList.vue) 是一个使用 `useSiteStore` 展示文章列表的示例。
> 分页功能可参考 [valaxy-theme-yun/pages/page/[page].vue](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-yun/pages/page/%5Bpage%5D.vue) 与 [valaxy-theme-yun/components/YunPostList.vue](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-yun/components/YunPostList.vue)。
#### 获取文章分类与标签
在你获取文章列表后,`site.postList` 中的每篇文章都具有 `categories`(分类) 与 `tags`(标签) 属性。
你还可以通过 `useCategories``useTags` 获取所有分类、标签,其中便包含了与文章的对应关系。
```ts
import { useCategories, useTags } from 'valaxy'
const categories = useCategories()
const tags = useTags()
```
- [valaxy/packages/valaxy-theme-yun/layouts/categories.vue](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-yun/layouts/categories.vue) 是一个使用 `useCategories` 展示文章分类的示例。
- [valaxy/packages/valaxy-theme-yun/layouts/tags.vue](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-yun/layouts/tags.vue) 是一个使用 `useTags` 展示文章标签的示例。([`useYunTags`](https://github.com/YunYouJun/valaxy/blob/main/packages/valaxy-theme-yun/composables/tags.ts) 是主题对 `useTags` 的封裝。)
> `useTags` 中的 `tags` 为一个对象,其键为标签名,值为对应的文章列表。
> `useCategories` 可传入参数 `category``useCategories('aaa')` 以获取指定分类的文章列表。
#### 获取 Front-matter
你可以通过 `useFrontmatter` 获取当前页面的 Front-matter。
譬如:
```vue
<script lang="ts" setup>
import { useFrontmatter } from 'valaxy'
const fm = useFrontmatter()
</script>
<template>
<h1>{{ fm.title }}</h1>
</template>
```
### 目录
如果你想要快速实现一个目录Valaxy 提供了一个内置钩子函数 `useOutline`

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { useCategory, useSiteStore, useTag } from 'valaxy'
import { useCategories, useSiteStore, useTags } from 'valaxy'
import { useI18n } from 'vue-i18n'
import { useThemeConfig } from '../composables'
@ -8,8 +8,8 @@ const { t } = useI18n()
const site = useSiteStore()
const themeConfig = useThemeConfig()
const categories = useCategory()
const tags = useTag()
const categories = useCategories()
const tags = useTags()
</script>
<template>

View File

@ -1,3 +1,4 @@
export * from './config'
export * from './helper'
export * from './post'
export * from './tags'

View File

@ -0,0 +1,36 @@
import { TinyColor } from '@ctrl/tinycolor'
import { useTags } from 'valaxy'
/**
* get utils about tags
*/
export function useYunTags(options: {
/**
* Primary Color
*/
primary: string
} = {
primary: '#0078E7',
}) {
const tags = useTags()
const gray = new TinyColor('#999999')
const primaryColor = new TinyColor(options.primary)
const getTagStyle = (count: number) => {
const counts = Array.from(tags.value).map(([_, value]) => value.count)
const max = Math.max(...counts)
const min = Math.min(...counts)
const range = max - min
const percent = (count - min) / range
return {
'--yun-tag-color': gray.mix(primaryColor, percent * 100).toString(),
'fontSize': `${percent * 36 + 12}px`,
}
}
return {
tags,
getTagStyle,
}
}

View File

@ -1,6 +1,6 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { useCategory, useFrontmatter, usePostTitle, useSiteStore } from 'valaxy'
import { useCategories, useFrontmatter, usePostTitle, useSiteStore } from 'valaxy'
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router'
import { defineWebPage, useSchemaOrg } from '@vueuse/schema-org'
@ -12,7 +12,7 @@ const frontmatter = useFrontmatter()
const route = useRoute()
const curCategory = computed(() => (route.query.category as string || ''))
const categories = useCategory()
const categories = useCategories()
const posts = computed(() => {
const list = site.postList.filter((post) => {

View File

@ -1,10 +1,10 @@
<script lang="ts" setup>
import { useFrontmatter, useInvisibleElement, usePostTitle, useSiteStore, useTags } from 'valaxy'
import { useFrontmatter, useInvisibleElement, usePostTitle, useSiteStore } from 'valaxy'
import { useI18n } from 'vue-i18n'
import { computed, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { defineWebPage, useSchemaOrg } from '@vueuse/schema-org'
import { useThemeConfig } from '../composables'
import { useThemeConfig, useYunTags } from '../composables'
useSchemaOrg([
defineWebPage({
@ -19,7 +19,7 @@ const themeConfig = useThemeConfig()
const { t } = useI18n()
const frontmatter = useFrontmatter()
const { tags, getTagStyle } = useTags({
const { tags, getTagStyle } = useYunTags({
primary: themeConfig.value.colors.primary,
})

View File

@ -42,7 +42,7 @@ export function isCategoryList(category: any): category is CategoryList {
* }
* @returns
*/
export function useCategory(category?: MaybeRef<string>, posts: Post[] = []) {
export function useCategories(category?: MaybeRef<string>, posts: Post[] = []) {
return computed(() => {
const categories = unref(category)
@ -154,3 +154,8 @@ export function removeItemFromCategory(categoryList: CategoryList, categoryName:
categoryList.children.splice(categoryListItemIndex, 1)
}
}
/**
* @deprecated use `useCategories` instead
*/
export const useCategory = useCategories

View File

@ -1,7 +1,7 @@
// for classify
export * from './category'
export * from './categories'
export * from './post'
export * from './tag'
export * from './tags'
// common
export * from './common'

View File

@ -1,4 +1,3 @@
import { TinyColor } from '@ctrl/tinycolor'
import { computed } from 'vue'
import type { Post } from '../..'
import { useSiteStore } from '../stores'
@ -7,46 +6,12 @@ export type Tags = Map<string, {
count: number
}>
/**
* get utils about tags
*/
export function useTags(options: {
/**
* Primary Color
*/
primary: string
} = {
primary: '#0078E7',
}) {
const tags = useTag()
const gray = new TinyColor('#999999')
const primaryColor = new TinyColor(options.primary)
const getTagStyle = (count: number) => {
const counts = Array.from(tags.value).map(([_, value]) => value.count)
const max = Math.max(...counts)
const min = Math.min(...counts)
const range = max - min
const percent = (count - min) / range
return {
'--yun-tag-color': gray.mix(primaryColor, percent * 100).toString(),
'fontSize': `${percent * 36 + 12}px`,
}
}
return {
tags,
getTagStyle,
}
}
/**
* get tag map
* [tagName]: count
* @returns
*/
export function useTag() {
export function useTags() {
const site = useSiteStore()
return computed(() => {
@ -78,3 +43,8 @@ export function useTag() {
return tagMap
})
}
/**
* @deprecated use `useTags` instead
*/
export const useTag = useTags