mirror of https://github.com/YunYouJun/valaxy
docs: how to write theme, use api useTags useCategories instead of useTag useCategory
This commit is contained in:
parent
fa9cda035a
commit
903c441f6d
|
@ -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`。
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export * from './config'
|
||||
export * from './helper'
|
||||
export * from './post'
|
||||
export * from './tags'
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
|
@ -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) => {
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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'
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue