@sugarat/theme 0.4.13 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/node.d.ts +13 -1
  2. package/node.js +147 -52
  3. package/node.mjs +755 -0
  4. package/package.json +13 -10
  5. package/src/components/BlogAlert.vue +10 -9
  6. package/src/components/BlogArticleAnalyze.vue +8 -9
  7. package/src/components/BlogAuthor.vue +6 -5
  8. package/src/components/BlogBackToTop.vue +8 -10
  9. package/src/components/BlogButtonAfterArticle.vue +5 -14
  10. package/src/components/BlogCommentWrapper.vue +11 -28
  11. package/src/components/BlogDocCover.vue +3 -3
  12. package/src/components/BlogFooter.vue +3 -1
  13. package/src/components/BlogFriendLink.vue +4 -3
  14. package/src/components/BlogHomeBanner.vue +7 -6
  15. package/src/components/BlogHomeHeaderAvatar.vue +3 -3
  16. package/src/components/BlogHomeOverview.vue +4 -4
  17. package/src/components/BlogHomeTags.vue +5 -5
  18. package/src/components/BlogHotArticle.vue +4 -7
  19. package/src/components/BlogItem.vue +4 -3
  20. package/src/components/BlogList.vue +7 -6
  21. package/src/components/BlogRecommendArticle.vue +11 -14
  22. package/src/components/BlogSidebar.vue +9 -15
  23. package/src/components/CommentArtalk.vue +7 -5
  24. package/src/components/CommentGiscus.vue +7 -8
  25. package/src/components/Icon.vue +33 -0
  26. package/src/composables/config/blog.ts +207 -89
  27. package/src/composables/config/index.ts +9 -0
  28. package/src/hooks/useOml2d.ts +15 -8
  29. package/src/index.ts +3 -0
  30. package/src/node.ts +5 -1
  31. package/src/styles/index.scss +6 -6
  32. package/src/utils/node/hot-reload-plugin.ts +31 -1
  33. package/src/utils/node/index.ts +0 -2
  34. package/src/utils/node/mdPlugins.ts +4 -0
  35. package/src/utils/node/theme.ts +15 -18
  36. package/src/utils/node/vitePlugins.ts +120 -34
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sugarat/theme",
3
- "version": "0.4.13",
3
+ "version": "0.5.1",
4
4
  "description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
5
5
  "author": "sugar",
6
6
  "license": "MIT",
@@ -20,6 +20,8 @@
20
20
  "exports": {
21
21
  "./node": {
22
22
  "types": "./node.d.ts",
23
+ "import": "./node.mjs",
24
+ "require": "./node.js",
23
25
  "default": "./node.js"
24
26
  },
25
27
  "./package.json": "./package.json",
@@ -29,6 +31,7 @@
29
31
  "files": [
30
32
  "node.d.ts",
31
33
  "node.js",
34
+ "node.mjs",
32
35
  "src",
33
36
  "types"
34
37
  ],
@@ -42,29 +45,29 @@
42
45
  "@mermaid-js/mermaid-mindmap": "^9.3.0",
43
46
  "@vue/shared": "^3.4.26",
44
47
  "@vueuse/core": "^9.13.0",
45
- "fast-glob": "^3.3.2",
46
48
  "markdown-it-task-checkbox": "^1.0.6",
47
49
  "mermaid": "^10.9.0",
48
50
  "oh-my-live2d": "^0.19.3",
49
51
  "swiper": "^11.1.1",
50
52
  "vitepress-markdown-timeline": "^1.2.1",
53
+ "vitepress-plugin-group-icons": "^1.2.4",
51
54
  "vitepress-plugin-mermaid": "2.0.13",
52
55
  "vitepress-plugin-tabs": "0.2.0",
53
- "@sugarat/theme-shared": "0.0.2",
54
- "vitepress-plugin-rss": "0.2.10",
55
- "vitepress-plugin-announcement": "0.1.1",
56
- "vitepress-plugin-pagefind": "0.4.10"
56
+ "@sugarat/theme-shared": "0.0.3",
57
+ "vitepress-plugin-pagefind": "0.4.10",
58
+ "vitepress-plugin-announcement": "0.1.3",
59
+ "vitepress-plugin-rss": "0.3.0"
57
60
  },
58
61
  "devDependencies": {
59
62
  "@element-plus/icons-vue": "^2.3.1",
60
63
  "artalk": "^2.8.5",
61
64
  "element-plus": "^2.7.2",
62
- "pagefind": "^1.1.0",
65
+ "pagefind": "^1.1.1",
63
66
  "sass": "^1.77.8",
64
67
  "typescript": "^5.4.5",
65
- "vite": "^5.2.11",
66
- "vitepress": "1.3.4",
67
- "vue": "^3.4.26",
68
+ "vite": "^5.4.9",
69
+ "vitepress": "1.4.1",
70
+ "vue": "^3.5.12",
68
71
  "vitepress-plugin-51la": "0.1.0"
69
72
  },
70
73
  "scripts": {
@@ -1,30 +1,31 @@
1
1
  <script lang="ts" setup>
2
2
  import { ElAlert } from 'element-plus'
3
3
  import { onMounted, ref } from 'vue'
4
- import { useBlogConfig } from '../composables/config/blog'
4
+ import { useAlertConfig } from '../composables/config/blog'
5
5
 
6
- const { alert: alertProps } = useBlogConfig()
6
+ // TODO:拆分插件,对标公告插件
7
+ const alertProps = useAlertConfig()
7
8
  const show = ref(false)
8
9
  const storageKey = 'theme-blog-alert'
9
10
  const closeFlag = `${storageKey}-close`
10
11
  onMounted(() => {
11
12
  // 取旧值
12
13
  const oldValue = localStorage.getItem(storageKey)
13
- const newValue = JSON.stringify(alertProps)
14
+ const newValue = JSON.stringify(alertProps.value)
14
15
  localStorage.setItem(storageKey, newValue)
15
16
 
16
17
  // >= 0 每次都展示,区别是否自动消失
17
- if (Number(alertProps?.duration) >= 0) {
18
+ if (Number(alertProps?.value?.duration) >= 0) {
18
19
  show.value = true
19
- if (alertProps?.duration) {
20
+ if (alertProps?.value?.duration) {
20
21
  setTimeout(() => {
21
22
  show.value = false
22
- }, alertProps?.duration)
23
+ }, alertProps?.value?.duration)
23
24
  }
24
25
  return
25
26
  }
26
27
 
27
- if (oldValue !== newValue && alertProps?.duration === -1) {
28
+ if (oldValue !== newValue && alertProps?.value?.duration === -1) {
28
29
  // 当做新值处理
29
30
  show.value = true
30
31
  localStorage.removeItem(closeFlag)
@@ -32,14 +33,14 @@ onMounted(() => {
32
33
  }
33
34
 
34
35
  // 新旧相等,判断是否点击过close,没点击关闭依然展示
35
- if (oldValue === newValue && alertProps?.duration === -1 && !localStorage.getItem(closeFlag)) {
36
+ if (oldValue === newValue && alertProps?.value?.duration === -1 && !localStorage.getItem(closeFlag)) {
36
37
  show.value = true
37
38
  }
38
39
  })
39
40
 
40
41
  function handleClose() {
41
42
  show.value = false
42
- if (alertProps?.duration === -1) {
43
+ if (alertProps?.value?.duration === -1) {
43
44
  localStorage.setItem(closeFlag, `${+new Date()}`)
44
45
  }
45
46
  }
@@ -11,14 +11,14 @@ import {
11
11
  EditPen,
12
12
  UserFilled
13
13
  } from '@element-plus/icons-vue'
14
- import { useAnalyzeTitles, useBlogConfig, useCurrentArticle, useDocMetaInsertPosition, useDocMetaInsertSelector, useFormatShowDate } from '../composables/config/blog'
14
+ import { useAnalyzeTitles, useArticleConfig, useAuthorList, useCurrentArticle, useDocMetaInsertPosition, useDocMetaInsertSelector, useFormatShowDate, useGlobalAuthor } from '../composables/config/blog'
15
15
  import countWord, { formatDate } from '../utils/client'
16
- import type { Theme } from '../composables/config'
17
16
  import BlogDocCover from './BlogDocCover.vue'
18
17
 
19
18
  const formatShowDate = useFormatShowDate()
20
- const { article, authorList } = useBlogConfig()
21
- const readingTimePosition = article?.readingTimePosition || 'inline'
19
+ const article = useArticleConfig()
20
+ const authorList = useAuthorList()
21
+ const readingTimePosition = computed(() => article?.value?.readingTimePosition || 'inline')
22
22
 
23
23
  const { frontmatter } = useData()
24
24
  const tags = computed(() => {
@@ -33,7 +33,7 @@ const tags = computed(() => {
33
33
  ]
34
34
  })
35
35
  const showAnalyze = computed(
36
- () => frontmatter.value?.readingTime ?? article?.readingTime ?? true
36
+ () => frontmatter.value?.readingTime ?? article?.value?.readingTime ?? true
37
37
  )
38
38
 
39
39
  const wordCount = ref(0)
@@ -102,7 +102,7 @@ onMounted(() => {
102
102
 
103
103
  const currentArticle = useCurrentArticle()
104
104
  const publishDate = computed(() => {
105
- return formatShowDate(currentArticle.value?.meta?.date || '')
105
+ return formatShowDate.value(currentArticle.value?.meta?.date || '')
106
106
  })
107
107
 
108
108
  const hoverDate = computed(() => {
@@ -111,15 +111,14 @@ const hoverDate = computed(() => {
111
111
 
112
112
  const hiddenTime = computed(() => frontmatter.value.date === false)
113
113
 
114
- const { theme } = useData<Theme.Config>()
115
- const globalAuthor = computed(() => theme.value.blog?.author || '')
114
+ const globalAuthor = useGlobalAuthor()
116
115
  const author = computed(
117
116
  () =>
118
117
  (frontmatter.value.author || currentArticle.value?.meta.author)
119
118
  ?? globalAuthor.value
120
119
  )
121
120
  const currentAuthorInfo = computed(() =>
122
- authorList?.find(v => author.value === v.nickname)
121
+ authorList?.value?.find(v => author.value === v.nickname)
123
122
  )
124
123
  const hiddenAuthor = computed(() => frontmatter.value.author === false)
125
124
 
@@ -1,20 +1,21 @@
1
1
  <script setup>
2
2
  import { useData, withBase } from 'vitepress'
3
3
  import { computed } from 'vue'
4
- import { useBlogConfig } from '../composables/config/blog'
4
+ import { useBlogConfig, useGlobalAuthor, useHomeConfig } from '../composables/config/blog'
5
5
 
6
- const { home } = useBlogConfig()
6
+ const home = useHomeConfig()
7
7
  const { frontmatter, site } = useData()
8
+ const globalAuthor = useGlobalAuthor()
8
9
  const author = computed(() =>
9
10
  frontmatter.value.author
10
11
  ?? frontmatter.value?.blog?.author
11
- ?? home?.author
12
- ?? site.value.themeConfig?.blog?.author
12
+ ?? home?.value?.author
13
+ ?? globalAuthor?.value
13
14
  )
14
15
  const logo = computed(() =>
15
16
  frontmatter.value?.logo
16
17
  ?? frontmatter.value?.blog?.logo
17
- ?? home?.logo
18
+ ?? home?.value?.logo
18
19
  ?? site.value?.themeConfig?.logo
19
20
  ?? '/logo.png'
20
21
  )
@@ -1,9 +1,8 @@
1
1
  <script lang="ts" setup>
2
2
  import { useElementSize, useScroll } from '@vueuse/core'
3
- import { ElIcon } from 'element-plus'
4
3
  import { computed, ref } from 'vue'
5
- import { vOuterHtml } from '../directives'
6
- import { useBackToTopConfig } from '../composables/config/blog'
4
+ import { useBackToTopConfig, useOpenBackToTop } from '../composables/config/blog'
5
+ import Icon from './Icon.vue'
7
6
 
8
7
  function handleBackRoTop() {
9
8
  window.scrollTo({ top: 0, behavior: 'smooth' })
@@ -15,29 +14,28 @@ const { width } = useElementSize(el)
15
14
  const docWidth = computed(() => `${width.value}px`)
16
15
 
17
16
  const backToTopConfig = useBackToTopConfig()
18
- const open = computed(() => !!(backToTopConfig ?? true))
17
+ const open = useOpenBackToTop()
19
18
 
20
19
  const { y } = useScroll(window)
21
20
  const defaultTriggerHeight = 450
22
- const triggerTop = computed(() => (typeof backToTopConfig === 'boolean' ? undefined : backToTopConfig?.top) ?? defaultTriggerHeight)
21
+ const triggerTop = computed(() => backToTopConfig.value?.top ?? defaultTriggerHeight)
23
22
 
24
23
  const show = computed(() => width && y.value > triggerTop.value)
25
24
 
26
- const iconSVGStr = computed(() => typeof backToTopConfig === 'boolean' ? '' : backToTopConfig?.icon)
25
+ const iconSVGStr = computed(() => backToTopConfig?.value?.icon)
27
26
  </script>
28
27
 
29
28
  <template>
30
29
  <div v-if="open" v-show="show" class="back-to-top">
31
30
  <span class="icon-wrapper" @click="handleBackRoTop">
32
- <ElIcon :size="20">
33
- <i v-if="iconSVGStr" v-outer-html="iconSVGStr" />
34
- <svg v-else width="512" height="512" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
31
+ <Icon :size="20" :icon="iconSVGStr">
32
+ <svg width="512" height="512" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
35
33
  <path
36
34
  fill="currentColor"
37
35
  d="m20 22l-3.86-1.55c.7-1.53 1.2-3.11 1.51-4.72zM7.86 20.45L4 22l2.35-6.27c.31 1.61.81 3.19 1.51 4.72M12 2s5 2 5 10c0 3.1-.75 5.75-1.67 7.83A2 2 0 0 1 13.5 21h-3a2 2 0 0 1-1.83-1.17C7.76 17.75 7 15.1 7 12c0-8 5-10 5-10m0 10c1.1 0 2-.9 2-2s-.9-2-2-2s-2 .9-2 2s.9 2 2 2"
38
36
  />
39
37
  </svg>
40
- </ElIcon>
38
+ </Icon>
41
39
  </span>
42
40
  </div>
43
41
  </template>
@@ -1,31 +1,22 @@
1
1
  <script lang="ts" setup>
2
2
  import { ElButton } from 'element-plus'
3
3
  import { computed, ref, watch } from 'vue'
4
- import { useData } from 'vitepress'
5
- import { useBlogConfig } from '../composables/config/blog'
4
+ import { useButtonAfterConfig } from '../composables/config/blog'
6
5
  import { aliPaySVG, weChatPaySVG } from '../constants/svg'
7
6
 
8
- const { buttonAfterArticle: _buttonAfterArticle } = useBlogConfig()
9
- const { frontmatter } = useData()
10
- const frontmatterConfig = computed(() => frontmatter.value.buttonAfterArticle)
11
-
12
- const buttonAfterArticleConfig = computed(() => {
13
- if (frontmatterConfig.value === false || (!frontmatterConfig.value && !_buttonAfterArticle)) {
14
- return false
15
- }
16
-
17
- return { ..._buttonAfterArticle, ...frontmatterConfig.value }
18
- })
7
+ const buttonAfterArticleConfig = useButtonAfterConfig()
19
8
 
20
9
  const showContent = ref(false)
21
10
 
22
11
  watch(buttonAfterArticleConfig, () => {
23
- showContent.value = !!buttonAfterArticleConfig.value?.expand
12
+ showContent.value = buttonAfterArticleConfig.value !== false && !!buttonAfterArticleConfig.value?.expand
24
13
  }, {
25
14
  immediate: true
26
15
  })
27
16
 
28
17
  const svg = computed(() => {
18
+ if (buttonAfterArticleConfig.value === false)
19
+ return ''
29
20
  const icon = buttonAfterArticleConfig.value?.icon
30
21
  if (icon === 'aliPay') {
31
22
  return aliPaySVG
@@ -1,12 +1,10 @@
1
1
  <script setup lang="ts">
2
2
  import { useElementSize, useElementVisibility, useWindowSize } from '@vueuse/core'
3
- import { useData } from 'vitepress'
4
- import { computed, h, ref } from 'vue'
5
- import { ElIcon } from 'element-plus'
3
+ import { computed, ref } from 'vue'
6
4
  import { Comment } from '@element-plus/icons-vue'
7
- import { useBlogConfig } from '../composables/config/blog'
5
+ import { useCommentConfig, useOpenCommentConfig } from '../composables/config/blog'
6
+ import Icon from './Icon.vue'
8
7
 
9
- const { frontmatter } = useData()
10
8
  const commentEl = ref(null)
11
9
  const commentIsVisible = useElementVisibility(commentEl)
12
10
 
@@ -17,28 +15,13 @@ function handleScrollToComment() {
17
15
  })
18
16
  }
19
17
 
20
- const { comment: _comment } = useBlogConfig()
21
- const commentConfig = computed(() =>
22
- _comment === false ? undefined : _comment
23
- )
18
+ const commentConfig = useCommentConfig()
24
19
 
25
- const show = computed(() => {
26
- return _comment && frontmatter.value.comment !== false
27
- })
20
+ const show = useOpenCommentConfig()
28
21
 
29
22
  const { width } = useWindowSize()
30
23
  const mobileMinify = computed(() => width.value < 768 && (commentConfig.value?.mobileMinify ?? true))
31
24
 
32
- const CommentIcon = commentConfig.value?.icon
33
- ? h('i', {
34
- onVnodeMounted(vnode) {
35
- if (vnode.el) {
36
- vnode.el.outerHTML = commentConfig.value?.icon
37
- }
38
- },
39
- })
40
- : h(Comment)
41
-
42
25
  const $vpDoc = document.querySelector('.vp-doc')
43
26
  const el = ref<any>($vpDoc)
44
27
  const { width: _docWidth } = useElementSize(el)
@@ -54,17 +37,17 @@ const labelText = computed(() => {
54
37
  <slot />
55
38
  <div v-show="!commentIsVisible" class="comment-btn-wrapper">
56
39
  <span v-if="!mobileMinify && labelText" class="icon-wrapper-text" @click="handleScrollToComment">
57
- <ElIcon :size="20">
58
- <CommentIcon />
59
- </ElIcon>
40
+ <Icon :size="20" :icon="commentConfig?.icon">
41
+ <Comment />
42
+ </Icon>
60
43
  <span class="text">
61
44
  {{ labelText }}
62
45
  </span>
63
46
  </span>
64
47
  <span v-else class="icon-wrapper" @click="handleScrollToComment">
65
- <ElIcon :size="20">
66
- <CommentIcon />
67
- </ElIcon>
48
+ <Icon :size="20" :icon="commentConfig?.icon">
49
+ <Comment />
50
+ </Icon>
68
51
  </span>
69
52
  </div>
70
53
  </div>
@@ -1,7 +1,7 @@
1
1
  <script lang="ts" setup>
2
2
  import { useData } from 'vitepress'
3
3
  import { computed } from 'vue'
4
- import { useBlogConfig, useCurrentArticle } from '../composables/config/blog'
4
+ import { useArticleConfig, useCurrentArticle } from '../composables/config/blog'
5
5
 
6
6
  const { frontmatter } = useData()
7
7
  const cover = computed(() => frontmatter.value.cover)
@@ -9,9 +9,9 @@ const cover = computed(() => frontmatter.value.cover)
9
9
  const currentArticle = useCurrentArticle()
10
10
  const realCover = computed<string>(() => import.meta.env.DEV ? cover.value : currentArticle.value?.meta?.cover)
11
11
 
12
- const { article } = useBlogConfig()
12
+ const article = useArticleConfig()
13
13
  const hiddenCover = computed(
14
- () => frontmatter.value?.hiddenCover ?? article?.hiddenCover ?? false
14
+ () => frontmatter.value?.hiddenCover ?? article?.value?.hiddenCover ?? false
15
15
  )
16
16
  </script>
17
17
 
@@ -5,9 +5,10 @@ import packageJSON from '../../package.json'
5
5
  import { copyrightSVG, icpSVG, themeSVG } from '../constants/svg'
6
6
  import { vOuterHtml } from '../directives'
7
7
 
8
- const footerData = useHomeFooterConfig()
8
+ const footerConfig = useHomeFooterConfig()
9
9
 
10
10
  const renderData = computed(() => {
11
+ const footerData = footerConfig.value
11
12
  if (!footerData) {
12
13
  return []
13
14
  }
@@ -104,6 +105,7 @@ const renderData = computed(() => {
104
105
  </a>
105
106
  <span v-else>{{ item.name }}</span>
106
107
  </span>
108
+ <!-- TODO: 理论上存在问题,待优化 -->
107
109
  <span v-else v-outer-html="item" />
108
110
  </template>
109
111
  </p>
@@ -3,7 +3,7 @@ import { ElAvatar } from 'element-plus'
3
3
  import { useDark, useIntervalFn } from '@vueuse/core'
4
4
  import { computed, onMounted, onUnmounted, ref } from 'vue'
5
5
  import Swiper from 'swiper'
6
- import { useBlogConfig } from '../composables/config/blog'
6
+ import { useFriendData } from '../composables/config/blog'
7
7
  import { getImageUrl, shuffleArray } from '../utils/client'
8
8
  import type { Theme } from '../'
9
9
  import { friendLinkSvgStr } from '../constants/svg'
@@ -12,13 +12,13 @@ const isDark = useDark({
12
12
  storageKey: 'vitepress-theme-appearance'
13
13
  })
14
14
 
15
- const { friend } = useBlogConfig()
15
+ const friendData = useFriendData()
16
16
  const friendConfig = computed<Theme.FriendConfig>(() => ({
17
17
  list: [],
18
18
  random: false,
19
19
  limit: Number.MAX_SAFE_INTEGER,
20
20
  title: `${friendLinkSvgStr}友情链接`,
21
- ...(Array.isArray(friend) ? { list: friend } : friend)
21
+ ...(Array.isArray(friendData.value) ? { list: friendData.value } : friendData.value)
22
22
  }))
23
23
 
24
24
  const limit = computed(() => {
@@ -89,6 +89,7 @@ onMounted(() => {
89
89
  }
90
90
  })
91
91
 
92
+ // TODO: SSR渲染支持
92
93
  onUnmounted(() => {
93
94
  pause()
94
95
  })
@@ -1,21 +1,21 @@
1
1
  <script setup lang="ts">
2
2
  import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
3
3
  import { useData } from 'vitepress'
4
- import { useBlogConfig } from '../composables/config/blog'
4
+ import { useHomeConfig } from '../composables/config/blog'
5
5
 
6
6
  const { site, frontmatter } = useData()
7
- const { home } = useBlogConfig()
7
+ const home = useHomeConfig()
8
8
 
9
9
  const name = computed(
10
- () => (frontmatter.value.blog?.name ?? site.value.title) || home?.name || ''
10
+ () => (frontmatter.value.blog?.name ?? site.value.title) || home?.value?.name || ''
11
11
  )
12
- const motto = computed(() => frontmatter.value.blog?.motto || home?.motto || '')
12
+ const motto = computed(() => frontmatter.value.blog?.motto || home?.value?.motto || '')
13
13
 
14
14
  const inspiring = ref('')
15
15
  const inspiringList = computed<string[]>(() => {
16
16
  return [
17
17
  ...new Set(
18
- [frontmatter.value.blog?.inspiring, home?.inspiring]
18
+ [frontmatter.value.blog?.inspiring, home?.value?.inspiring]
19
19
  .flat()
20
20
  .filter(v => !!v)
21
21
  )
@@ -23,7 +23,7 @@ const inspiringList = computed<string[]>(() => {
23
23
  })
24
24
  const inspiringIndex = ref<number>(-1)
25
25
  const inspiringTimeout = computed<number>(
26
- () => frontmatter.value.blog?.inspiringTimeout || home?.inspiringTimeout || 0
26
+ () => frontmatter.value.blog?.inspiringTimeout || home?.value?.inspiringTimeout || 0
27
27
  )
28
28
 
29
29
  watch(inspiringTimeout, () => {
@@ -50,6 +50,7 @@ onUnmounted(() => {
50
50
  }
51
51
  })
52
52
 
53
+ // TODO:SSR 支持
53
54
  async function changeSlogan() {
54
55
  // 顺手启动定时器
55
56
  startTimer()
@@ -1,14 +1,14 @@
1
1
  <script setup lang="ts">
2
2
  import { useData, withBase } from 'vitepress'
3
3
  import { computed } from 'vue'
4
- import { useBlogConfig } from '../composables/config/blog'
4
+ import { useHomeConfig } from '../composables/config/blog'
5
5
 
6
- const { home } = useBlogConfig()
6
+ const home = useHomeConfig()
7
7
  const { frontmatter, site } = useData()
8
8
  const logo = computed(() =>
9
9
  frontmatter.value.logo
10
10
  ?? frontmatter.value?.blog?.logo
11
- ?? home?.logo
11
+ ?? home?.value?.logo
12
12
  ?? site.value.themeConfig?.logo
13
13
  ?? '/logo.png'
14
14
  )
@@ -2,12 +2,12 @@
2
2
  import { computed } from 'vue'
3
3
  import { useData } from 'vitepress'
4
4
  import { isCurrentWeek } from '../utils/client'
5
- import { useArticles, useBlogConfig, useHomeAnalysis } from '../composables/config/blog'
5
+ import { useArticles, useHomeAnalysis, useHomeConfig } from '../composables/config/blog'
6
6
  import BlogAuthor from './BlogAuthor.vue'
7
7
 
8
- const { home } = useBlogConfig()
8
+ const home = useHomeConfig()
9
9
  const { frontmatter } = useData()
10
- const avatarMode = computed(() => frontmatter.value?.blog?.avatarMode || home?.avatarMode || 'card')
10
+ const avatarMode = computed(() => frontmatter.value?.blog?.avatarMode || home?.value?.avatarMode || 'card')
11
11
 
12
12
  const showCardAvatar = computed(() => avatarMode.value === 'card')
13
13
  const showSplitCard = computed(() => avatarMode.value === 'split')
@@ -33,7 +33,7 @@ const currentWeek = computed(() => {
33
33
  })
34
34
 
35
35
  const analysis = useHomeAnalysis()
36
- const titles = computed(() => (frontmatter.value?.blog?.analysis?.articles?.title || analysis?.articles?.title || []))
36
+ const titles = computed(() => (frontmatter.value?.blog?.analysis?.articles?.title || analysis?.value?.articles?.title || []))
37
37
  </script>
38
38
 
39
39
  <template>
@@ -6,18 +6,18 @@ import { useRoute, useRouter } from 'vitepress'
6
6
  import {
7
7
  useActiveTag,
8
8
  useArticles,
9
- useConfig,
10
9
  useCurrentPageNum,
10
+ useHomeTagsConfig,
11
11
  } from '../composables/config/blog'
12
12
  import { tagsSvgStr } from '../constants/svg'
13
13
 
14
14
  const route = useRoute()
15
15
  const docs = useArticles()
16
- const homeTagsConfig = useConfig()?.config?.blog?.homeTags
17
- const showTags = computed(() => !!(homeTagsConfig ?? true))
18
- const title = computed(() => (typeof homeTagsConfig === 'boolean' || !homeTagsConfig?.title)
16
+ const homeTagsConfig = useHomeTagsConfig()
17
+ const showTags = computed(() => !!(homeTagsConfig.value ?? true))
18
+ const title = computed(() => (typeof homeTagsConfig.value === 'boolean' || !homeTagsConfig.value?.title)
19
19
  ? `${tagsSvgStr}标签`
20
- : homeTagsConfig?.title
20
+ : homeTagsConfig.value?.title
21
21
  )
22
22
  const tags = computed(() => {
23
23
  return [...new Set(docs.value.map(v => v.meta.tag || []).flat(3))]
@@ -2,17 +2,14 @@
2
2
  import { computed, ref } from 'vue'
3
3
  import { ElButton } from 'element-plus'
4
4
  import { useRouter, withBase } from 'vitepress'
5
- import { useArticles, useBlogConfig, useCleanUrls, useFormatShowDate } from '../composables/config/blog'
5
+ import { useArticles, useCleanUrls, useFormatShowDate, useHotArticleConfig, useShowHotArticle } from '../composables/config/blog'
6
6
  import { wrapperCleanUrls } from '../utils/client'
7
7
  import { fireSVG } from '../constants/svg'
8
8
 
9
9
  const formatShowDate = useFormatShowDate()
10
10
 
11
- const { hotArticle: _hotArticle } = useBlogConfig()
12
-
13
- const hotArticle = computed(() =>
14
- _hotArticle === false ? undefined : _hotArticle
15
- )
11
+ const hotArticle = useHotArticleConfig()
12
+ const show = useShowHotArticle()
16
13
 
17
14
  const title = computed(() => hotArticle.value?.title || `${fireSVG}精选文章`)
18
15
  const nextText = computed(() => hotArticle.value?.nextText || '换一组')
@@ -56,7 +53,7 @@ const showChangeBtn = computed(() => {
56
53
 
57
54
  <template>
58
55
  <div
59
- v-if="_hotArticle !== false && (recommendList.length || empty)" class="card recommend"
56
+ v-if="show && (recommendList.length || empty)" class="card recommend"
60
57
  data-pagefind-ignore="all"
61
58
  >
62
59
  <!-- 头部 -->
@@ -20,7 +20,7 @@ const props = defineProps<{
20
20
  const formatShowDate = useFormatShowDate()
21
21
 
22
22
  const showTime = computed(() => {
23
- return formatShowDate(props.date)
23
+ return formatShowDate.value(props.date)
24
24
  })
25
25
  const cleanUrls = useCleanUrls()
26
26
  const link = computed(() => withBase(wrapperCleanUrls(!!cleanUrls, props.route)))
@@ -30,14 +30,15 @@ function handleSkipDoc() {
30
30
  router.go(link.value)
31
31
  }
32
32
 
33
- const { coverPreview } = useImageStyle()
33
+ const imageStyle = useImageStyle()
34
+ const coverPreview = computed(() => imageStyle.value.coverPreview)
34
35
 
35
36
  const resultCover = computed(() => {
36
37
  if (!props.cover) {
37
38
  return ''
38
39
  }
39
40
  const baseCover = withBase(props.cover)
40
- const coverRule = [coverPreview]
41
+ const coverRule = [coverPreview.value]
41
42
  .flat()
42
43
  .filter(v => !!v)
43
44
  .find((coverRule) => {
@@ -5,14 +5,15 @@ import { useData, useRoute, useRouter } from 'vitepress'
5
5
  import {
6
6
  useActiveTag,
7
7
  useArticles,
8
- useBlogConfig,
9
- useCurrentPageNum
8
+ useCurrentPageNum,
9
+ useGlobalAuthor,
10
+ useHomeConfig
10
11
  } from '../composables/config/blog'
11
12
  import type { Theme } from '../composables/config'
12
13
  import BlogItem from './BlogItem.vue'
13
14
 
14
- const { theme, frontmatter } = useData<Theme.Config>()
15
- const globalAuthor = computed(() => theme.value.blog?.author || '')
15
+ const { frontmatter } = useData<Theme.Config>()
16
+ const globalAuthor = useGlobalAuthor()
16
17
  const docs = useArticles()
17
18
 
18
19
  const activeTag = useActiveTag()
@@ -41,9 +42,9 @@ const filterData = computed(() => {
41
42
  )
42
43
  })
43
44
 
44
- const { home } = useBlogConfig()
45
+ const home = useHomeConfig()
45
46
  const pageSize = computed(
46
- () => frontmatter.value.blog?.pageSize || home?.pageSize || 6
47
+ () => frontmatter.value.blog?.pageSize || home?.value?.pageSize || 6
47
48
  )
48
49
  const currentPage = useCurrentPageNum()
49
50
  const currentWikiData = computed(() => {