@sugarat/theme 0.1.49 → 0.2.0

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 (37) hide show
  1. package/node.d.ts +41 -1
  2. package/node.js +24 -20
  3. package/package.json +24 -24
  4. package/src/components/BlogAlert.vue +17 -17
  5. package/src/components/BlogApp.vue +91 -50
  6. package/src/components/BlogArticleAnalyze.vue +56 -57
  7. package/src/components/BlogAuthor.vue +55 -0
  8. package/src/components/BlogComment.vue +53 -50
  9. package/src/components/BlogDocCover.vue +4 -4
  10. package/src/components/BlogFooter.vue +131 -0
  11. package/src/components/BlogFriendLink.vue +40 -31
  12. package/src/components/BlogHomeBanner.vue +22 -16
  13. package/src/components/BlogHomeInfo.vue +4 -0
  14. package/src/components/BlogHomeOverview.vue +20 -20
  15. package/src/components/BlogHomeTags.vue +49 -40
  16. package/src/components/BlogHotArticle.vue +43 -36
  17. package/src/components/BlogImagePreview.vue +7 -5
  18. package/src/components/BlogItem.vue +42 -43
  19. package/src/components/BlogList.vue +46 -42
  20. package/src/components/BlogPopover.vue +41 -39
  21. package/src/components/BlogRecommendArticle.vue +58 -48
  22. package/src/components/BlogSearch.vue +143 -145
  23. package/src/components/UserWorks.vue +214 -210
  24. package/src/composables/config/blog.ts +14 -5
  25. package/src/composables/config/index.ts +74 -31
  26. package/src/constants/svg.ts +11 -2
  27. package/src/index.ts +1 -2
  28. package/src/node.ts +2 -2
  29. package/src/styles/gongan.png +0 -0
  30. package/src/styles/scss/global.scss +0 -5
  31. package/src/utils/client/index.ts +9 -8
  32. package/src/utils/node/genFeed.ts +8 -7
  33. package/src/utils/node/index.ts +8 -6
  34. package/src/utils/node/mdPlugins.ts +29 -22
  35. package/src/utils/node/theme.ts +16 -13
  36. package/src/utils/node/vitePlugins.ts +7 -6
  37. package/types/vue-shim.d.ts +1 -1
@@ -1,12 +1,186 @@
1
+ <script lang="ts" setup>
2
+ import { ElCarousel, ElCarouselItem, ElImage, ElMessage } from 'element-plus'
3
+ import VPDocAsideOutline from 'vitepress/dist/client/theme-default/components/VPDocAsideOutline.vue'
4
+ import { computed, reactive, ref, watch, watchEffect } from 'vue'
5
+ import { slugify } from '@mdit-vue/shared'
6
+ import { useWindowSize } from '@vueuse/core'
7
+ import {
8
+ formatDate,
9
+ getGithubDirUpdateTime,
10
+ getGithubUpdateTime
11
+ } from '../utils/client'
12
+ import {
13
+ useActiveAnchor,
14
+ useAutoUpdateAnchor,
15
+ useUserWorks
16
+ } from '../composables/config/blog'
17
+ import type { Theme } from '../composables/config'
18
+
19
+ const currentAnchor = useAutoUpdateAnchor()
20
+ // 更新锚点的时候更新 url 中的 hash
21
+ watch(
22
+ () => currentAnchor.id,
23
+ (val) => {
24
+ if (val) {
25
+ window.history.replaceState(null, '', `#${val}`)
26
+ }
27
+ }
28
+ )
29
+ const mountActiveAnchorEl = useActiveAnchor()
30
+ watch(mountActiveAnchorEl, () => {
31
+ const { value } = mountActiveAnchorEl
32
+ if (value) {
33
+ value.scroll({
34
+ behavior: 'smooth'
35
+ })
36
+ }
37
+ })
38
+
39
+ const works = useUserWorks()
40
+ const workList = reactive<
41
+ (Theme.UserWork & {
42
+ year?: string | undefined
43
+ startTime: string
44
+ lastUpdate?: string
45
+ endTime?: string
46
+ covers?: string[]
47
+ coverLayout?: string
48
+ })[]
49
+ >([])
50
+
51
+ // 格式化数据
52
+ watch(
53
+ works,
54
+ (val) => {
55
+ const sortDate = [...val.list].map((v) => {
56
+ const { time } = v
57
+
58
+ // 格式化时间
59
+ const metaInfo
60
+ = typeof time === 'string'
61
+ ? {
62
+ startTime: time,
63
+ endTime: '',
64
+ lastUpdate: ''
65
+ }
66
+ : {
67
+ startTime: time.start,
68
+ endTime: time.end,
69
+ lastUpdate: time.lastupdate
70
+ }
71
+
72
+ // 格式化封面信息
73
+ const covers: string[] = []
74
+ let coverLayout = 'swiper'
75
+
76
+ if (typeof v.cover === 'string') {
77
+ covers.push(v.cover)
78
+ }
79
+ else if (Array.isArray(v.cover)) {
80
+ covers.push(...v.cover)
81
+ }
82
+ else if (typeof v.cover === 'object') {
83
+ covers.push(...v.cover.urls)
84
+ coverLayout = v.cover.layout ?? coverLayout
85
+ }
86
+ return {
87
+ ...v,
88
+ ...metaInfo,
89
+ covers,
90
+ coverLayout
91
+ }
92
+ })
93
+ // 过滤出置顶数据
94
+ const topDate = sortDate.filter(v => v.top !== undefined)
95
+ const normalDate = sortDate.filter(v => v.top === undefined)
96
+ // 数据排序
97
+ topDate.sort((a, b) => a.top! - b.top!)
98
+ normalDate.sort((a, b) => +new Date(b.startTime) - +new Date(a.startTime))
99
+ if (topDate.length) {
100
+ // @ts-expect-error
101
+ topDate[0].year = works.value.topTitle ?? '置顶'
102
+ }
103
+ // 数据分组
104
+ const groupDate = normalDate.reduce((prev, cur) => {
105
+ const { startTime } = cur
106
+ const year = new Date(startTime).getFullYear()
107
+ const data = { ...cur }
108
+ if (!prev[year]) {
109
+ prev[year] = []
110
+ // 第一项数据加上year属性
111
+ // @ts-expect-error
112
+ data.year = year
113
+ }
114
+ prev[year].push(data)
115
+ return prev
116
+ }, {} as Record<string, (Theme.UserWork & { year?: string; startTime: string })[]>)
117
+ workList.push(...topDate, ...Object.values(groupDate).reverse().flat())
118
+ },
119
+ { immediate: true }
120
+ )
121
+
122
+ const init = ref(true)
123
+ // 更新时间信息
124
+ watchEffect(() => {
125
+ if (workList.length && init.value) {
126
+ init.value = false
127
+ workList.forEach((data) => {
128
+ // 接口获取最后更新时间
129
+ if (!data.lastUpdate && data.github) {
130
+ data.lastUpdate = '获取中...'
131
+ const { github } = data
132
+ if (typeof github === 'string') {
133
+ getGithubUpdateTime(github)
134
+ .then((time) => {
135
+ data.lastUpdate = formatDate(time, 'yyyy-MM-dd')
136
+ })
137
+ .catch(() => {
138
+ data.lastUpdate = '地址解析失败'
139
+ })
140
+ }
141
+ else {
142
+ const { owner, repo, path, branch } = github
143
+ // 拼接Github链接
144
+ let githubUrl = `https://github.com/${owner}/${repo}`
145
+ if (path) {
146
+ githubUrl += `/tree/${branch || 'master'}/${path}`
147
+ }
148
+ else if (branch) {
149
+ githubUrl += `/tree/${branch}`
150
+ }
151
+ data.github = githubUrl
152
+ getGithubDirUpdateTime(owner, repo, path ?? '', branch)
153
+ .then((time) => {
154
+ data.lastUpdate = formatDate(time, 'yyyy-MM-dd')
155
+ })
156
+ .catch(() => {
157
+ data.lastUpdate = '地址解析失败'
158
+ })
159
+ }
160
+ }
161
+ })
162
+ }
163
+ })
164
+
165
+ const { width } = useWindowSize()
166
+ const isCardMode = computed(() => width.value > 768)
167
+ function handleChooseTag(tag: string) {
168
+ ElMessage({
169
+ message: `点击了${tag}标签,标签过滤功能开发中ing...`,
170
+ type: 'warning'
171
+ })
172
+ }
173
+ </script>
174
+
1
175
  <template>
2
176
  <div class="user-works-page VPDoc">
3
177
  <div class="aside-container">
4
178
  <!-- TODO:过滤,可吸顶 -->
5
179
  <div class="filter">
6
180
  <!-- 时间: -->
7
- <div></div>
181
+ <div />
8
182
  <!-- TODO: tags -->
9
- <div></div>
183
+ <div />
10
184
  </div>
11
185
  </div>
12
186
  <!-- 作品列表 -->
@@ -16,21 +190,23 @@
16
190
  {{ works.description }}
17
191
  </p>
18
192
  <!-- 标题,描述信息,时间,线上链接,代码仓库,示例图片(几张,多种展示样式支持) -->
19
- <div class="work" v-for="(work, idx) in workList" :key="idx">
193
+ <div v-for="(work, idx) in workList" :key="idx" class="work">
20
194
  <!-- 大日期标题 -->
21
- <h2 :id="`work_${work.year}`" v-if="work.year">
195
+ <h2 v-if="work.year" :id="`work_${work.year}`">
22
196
  <a :href="`#work_${work.year}`">{{ work.year }}</a>
23
197
  </h2>
24
198
  <!-- 作品标题 -->
25
- <h3 class="title" :id="slugify(work.title)">
26
- <a class="pin" :href="'#' + slugify(work.title)"></a>
199
+ <h3 :id="slugify(work.title)" class="title">
200
+ <a class="pin" :href="`#${slugify(work.title)}`" />
27
201
  <a v-if="work.url" rel="noopener" target="_blank" :href="work.url">{{
28
202
  work.title
29
203
  }}</a>
30
204
  <span v-else>{{ work.title }}</span>
31
- <Badge v-if="work.status" :type="work.status?.type || 'tip'">{{
32
- work.status.text
33
- }}</Badge>
205
+ <Badge v-if="work.status" :type="work.status?.type || 'tip'">
206
+ {{
207
+ work.status.text
208
+ }}
209
+ </Badge>
34
210
  </h3>
35
211
  <!-- 补充信息 -->
36
212
  <div class="info">
@@ -46,18 +222,18 @@
46
222
  <path
47
223
  d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8s8 3.58 8 8s-3.58 8-8 8zm-.22-13h-.06c-.4 0-.72.32-.72.72v4.72c0 .35.18.68.49.86l4.15 2.49c.34.2.78.1.98-.24a.71.71 0 0 0-.25-.99l-3.87-2.3V7.72c0-.4-.32-.72-.72-.72z"
48
224
  fill="currentColor"
49
- ></path>
225
+ />
50
226
  </svg>
51
227
  </span>
52
228
  <span>{{ work.startTime }}</span>
53
229
  <span v-if="work.endTime"> - {{ work.endTime }}</span>
54
230
  </div>
55
- <!-- GitHub links-->
56
- <div class="links" v-if="work.github">
231
+ <!-- GitHub links -->
232
+ <div v-if="work.github" class="links">
57
233
  <a
58
- class="github-link"
59
234
  v-if="work.github"
60
- :href="(work.github as string)"
235
+ class="github-link"
236
+ :href="work.github as string"
61
237
  target="_blank"
62
238
  rel="noopener"
63
239
  >
@@ -70,17 +246,15 @@
70
246
  <path
71
247
  d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6c-3.3.3-5.6-1.3-5.6-3.6c0-2 2.3-3.6 5.2-3.6c3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9c2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9c.3 2 2.9 3.3 5.9 2.6c2.9-.7 4.9-2.6 4.6-4.6c-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2c12.8 2.3 17.3-5.6 17.3-12.1c0-6.2-.3-40.4-.3-61.4c0 0-70 15-84.7-29.8c0 0-11.4-29.1-27.8-36.6c0 0-22.9-15.7 1.6-15.4c0 0 24.9 2 38.6 25.8c21.9 38.6 58.6 27.5 72.9 20.9c2.3-16 8.8-27.1 16-33.7c-55.9-6.2-112.3-14.3-112.3-110.5c0-27.5 7.6-41.3 23.6-58.9c-2.6-6.5-11.1-33.3 2.6-67.9c20.9-6.5 69 27 69 27c20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27c13.7 34.7 5.2 61.4 2.6 67.9c16 17.7 25.8 31.5 25.8 58.9c0 96.5-58.9 104.2-114.8 110.5c9.2 7.9 17 22.9 17 46.4c0 33.7-.3 75.4-.3 83.6c0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252C496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2c1.6 1.6 3.9 2.3 5.2 1c1.3-1 1-3.3-.7-5.2c-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9c1.6 1 3.6.7 4.3-.7c.7-1.3-.3-2.9-2.3-3.9c-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2c2.3 2.3 5.2 2.6 6.5 1c1.3-1.3.7-4.3-1.3-6.2c-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9c1.6 2.3 4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2c-1.4-2.3-4-3.3-5.6-2z"
72
248
  fill="currentColor"
73
- ></path>
249
+ />
74
250
  </svg>
75
251
  </i>
76
- <span class="lastupdate" v-if="work.lastUpdate"
77
- >最后更新时间:{{ work.lastUpdate }}</span
78
- >
252
+ <span v-if="work.lastUpdate" class="lastupdate">最后更新时间:{{ work.lastUpdate }}</span>
79
253
  </a>
80
254
  </div>
81
255
  <!-- 其它自定义链接 -->
82
- <div class="links" v-if="work.links?.length">
83
- <i class="icon" v-if="work.links?.length">
256
+ <div v-if="work.links?.length" class="links">
257
+ <i v-if="work.links?.length" class="icon">
84
258
  <svg
85
259
  xmlns="http://www.w3.org/2000/svg"
86
260
  xmlns:xlink="http://www.w3.org/1999/xlink"
@@ -95,18 +269,18 @@
95
269
  >
96
270
  <path
97
271
  d="M10 14a3.5 3.5 0 0 0 5 0l4-4a3.5 3.5 0 0 0-5-5l-.5.5"
98
- ></path>
272
+ />
99
273
  <path
100
274
  d="M14 10a3.5 3.5 0 0 0-5 0l-4 4a3.5 3.5 0 0 0 5 5l.5-.5"
101
- ></path>
275
+ />
102
276
  </g>
103
277
  </svg>
104
278
  </i>
105
279
  <a
106
- class="link"
107
280
  v-for="link in work.links || []"
108
- :href="link.url"
109
281
  :key="link.url"
282
+ class="link"
283
+ :href="link.url"
110
284
  :title="link.title"
111
285
  target="_blank"
112
286
  rel="noopener"
@@ -115,7 +289,7 @@
115
289
  </a>
116
290
  </div>
117
291
  <!-- tags -->
118
- <div class="tags" v-if="work.tags?.length">
292
+ <div v-if="work.tags?.length" class="tags">
119
293
  <i class="icon">
120
294
  <svg
121
295
  xmlns="http://www.w3.org/2000/svg"
@@ -125,48 +299,48 @@
125
299
  <path
126
300
  fill="currentColor"
127
301
  d="M256 128v698.88l196.032-156.864a96 96 0 0 1 119.936 0L768 826.816V128H256zm-32-64h576a32 32 0 0 1 32 32v797.44a32 32 0 0 1-51.968 24.96L531.968 720a32 32 0 0 0-39.936 0L243.968 918.4A32 32 0 0 1 192 893.44V96a32 32 0 0 1 32-32z"
128
- ></path>
302
+ />
129
303
  </svg>
130
304
  </i>
131
305
  <span
132
- @click="handleChooseTag(tag)"
133
- class="tag"
134
306
  v-for="tag in work.tags"
135
307
  :key="tag"
136
- >{{ tag }}
308
+ class="tag"
309
+ @click="handleChooseTag(tag)"
310
+ >{{ tag }}
137
311
  </span>
138
312
  </div>
139
313
  </div>
140
314
  <!-- 封面图 -->
141
- <div class="images" v-if="work.covers?.length">
315
+ <div v-if="work.covers?.length" class="images">
142
316
  <!-- swiper -->
143
317
  <div v-if="work.coverLayout === 'swiper'" class="swiper-mode">
144
- <el-carousel
318
+ <ElCarousel
145
319
  autoplay
146
320
  height="260px"
147
321
  :type="isCardMode && work.covers.length >= 3 ? 'card' : ''"
148
322
  >
149
- <el-carousel-item
150
- style="text-align: center"
323
+ <ElCarouselItem
151
324
  v-for="(url, idx) in work.covers"
152
325
  :key="url"
326
+ style="text-align: center"
153
327
  >
154
- <el-image
155
- preview-teleported
328
+ <ElImage
156
329
  :key="url"
330
+ preview-teleported
157
331
  :src="url"
158
332
  loading="lazy"
159
333
  :preview-src-list="work.covers"
160
334
  :initial-index="idx"
161
335
  hide-on-click-modal
162
- :alt="work.title + '-' + idx"
336
+ :alt="`${work.title}-${idx}`"
163
337
  />
164
- </el-carousel-item>
165
- </el-carousel>
338
+ </ElCarouselItem>
339
+ </ElCarousel>
166
340
  </div>
167
341
  <!-- list -->
168
342
  <div v-if="work.coverLayout === 'list'" class="list-mode">
169
- <el-image
343
+ <ElImage
170
344
  v-for="(url, idx) in work.covers"
171
345
  :key="url"
172
346
  :src="url"
@@ -177,7 +351,7 @@
177
351
  />
178
352
  </div>
179
353
  </div>
180
- <div class="description" v-html="work.description"></div>
354
+ <div class="description" v-html="work.description" />
181
355
  </div>
182
356
  </div>
183
357
  <div class="aside-container">
@@ -188,176 +362,6 @@
188
362
  </div>
189
363
  </template>
190
364
 
191
- <script lang="ts" setup>
192
- import { ElImage, ElCarousel, ElCarouselItem, ElMessage } from 'element-plus'
193
- import VPDocAsideOutline from 'vitepress/dist/client/theme-default/components/VPDocAsideOutline.vue'
194
- import { computed, reactive, ref, watch, watchEffect } from 'vue'
195
- import { slugify } from '@mdit-vue/shared'
196
- import { useWindowSize } from '@vueuse/core'
197
- import {
198
- getGithubUpdateTime,
199
- formatDate,
200
- getGithubDirUpdateTime
201
- } from '../utils/client'
202
- import {
203
- useUserWorks,
204
- useActiveAnchor,
205
- useAutoUpdateAnchor
206
- } from '../composables/config/blog'
207
- import { Theme } from '../composables/config'
208
-
209
- const currentAnchor = useAutoUpdateAnchor()
210
- // 更新锚点的时候更新 url 中的 hash
211
- watch(
212
- () => currentAnchor.id,
213
- (val) => {
214
- if (val) {
215
- window.history.replaceState(null, '', `#${val}`)
216
- }
217
- }
218
- )
219
- const mountActiveAnchorEl = useActiveAnchor()
220
- watch(mountActiveAnchorEl, () => {
221
- const { value } = mountActiveAnchorEl
222
- if (value) {
223
- value.scroll({
224
- behavior: 'smooth'
225
- })
226
- }
227
- })
228
-
229
- const works = useUserWorks()
230
- const workList = reactive<
231
- (Theme.UserWork & {
232
- year?: string | undefined
233
- startTime: string
234
- lastUpdate?: string
235
- endTime?: string
236
- covers?: string[]
237
- coverLayout?: string
238
- })[]
239
- >([])
240
-
241
- // 格式化数据
242
- watch(
243
- works,
244
- (val) => {
245
- const sortDate = [...val.list].map((v) => {
246
- const { time } = v
247
-
248
- // 格式化时间
249
- const metaInfo =
250
- typeof time === 'string'
251
- ? {
252
- startTime: time,
253
- endTime: '',
254
- lastUpdate: ''
255
- }
256
- : {
257
- startTime: time.start,
258
- endTime: time.end,
259
- lastUpdate: time.lastupdate
260
- }
261
-
262
- // 格式化封面信息
263
- const covers: string[] = []
264
- let coverLayout = 'swiper'
265
-
266
- if (typeof v.cover === 'string') {
267
- covers.push(v.cover)
268
- } else if (Array.isArray(v.cover)) {
269
- covers.push(...v.cover)
270
- } else if (typeof v.cover === 'object') {
271
- covers.push(...v.cover.urls)
272
- coverLayout = v.cover.layout ?? coverLayout
273
- }
274
- return {
275
- ...v,
276
- ...metaInfo,
277
- covers,
278
- coverLayout
279
- }
280
- })
281
- // 过滤出置顶数据
282
- const topDate = sortDate.filter((v) => v.top !== undefined)
283
- const normalDate = sortDate.filter((v) => v.top === undefined)
284
- // 数据排序
285
- topDate.sort((a, b) => a.top! - b.top!)
286
- normalDate.sort((a, b) => +new Date(b.startTime) - +new Date(a.startTime))
287
- if (topDate.length) {
288
- // @ts-ignore
289
- topDate[0].year = works.value.topTitle ?? '置顶'
290
- }
291
- // 数据分组
292
- const groupDate = normalDate.reduce((prev, cur) => {
293
- const { startTime } = cur
294
- const year = new Date(startTime).getFullYear()
295
- const data = { ...cur }
296
- if (!prev[year]) {
297
- prev[year] = []
298
- // 第一项数据加上year属性
299
- // @ts-ignore
300
- data.year = year
301
- }
302
- prev[year].push(data)
303
- return prev
304
- }, {} as Record<string, (Theme.UserWork & { year?: string; startTime: string })[]>)
305
- workList.push(...topDate, ...Object.values(groupDate).reverse().flat())
306
- },
307
- { immediate: true }
308
- )
309
-
310
- const init = ref(true)
311
- // 更新时间信息
312
- watchEffect(() => {
313
- if (workList.length && init.value) {
314
- init.value = false
315
- workList.forEach((data) => {
316
- // 接口获取最后更新时间
317
- if (!data.lastUpdate && data.github) {
318
- data.lastUpdate = '获取中...'
319
- const { github } = data
320
- if (typeof github === 'string') {
321
- getGithubUpdateTime(github)
322
- .then((time) => {
323
- data.lastUpdate = formatDate(time, 'yyyy-MM-dd')
324
- })
325
- .catch(() => {
326
- data.lastUpdate = '地址解析失败'
327
- })
328
- } else {
329
- const { owner, repo, path, branch } = github
330
- // 拼接Github链接
331
- let githubUrl = `https://github.com/${owner}/${repo}`
332
- if (path) {
333
- githubUrl += `/tree/${branch || 'master'}/${path}`
334
- } else if (branch) {
335
- githubUrl += `/tree/${branch}`
336
- }
337
- data.github = githubUrl
338
- getGithubDirUpdateTime(owner, repo, path ?? '', branch)
339
- .then((time) => {
340
- data.lastUpdate = formatDate(time, 'yyyy-MM-dd')
341
- })
342
- .catch(() => {
343
- data.lastUpdate = '地址解析失败'
344
- })
345
- }
346
- }
347
- })
348
- }
349
- })
350
-
351
- const { width } = useWindowSize()
352
- const isCardMode = computed(() => width.value > 768)
353
- const handleChooseTag = (tag: string) => {
354
- ElMessage({
355
- message: `点击了${tag}标签,标签过滤功能开发中ing...`,
356
- type: 'warning'
357
- })
358
- }
359
- </script>
360
-
361
365
  <style lang="scss" scoped>
362
366
  .user-works-page {
363
367
  display: flex;
@@ -1,15 +1,17 @@
1
1
  import { useData, useRoute, withBase } from 'vitepress'
2
- import {
2
+ import type {
3
3
  Component,
4
+ InjectionKey,
5
+ Ref
6
+ } from 'vue'
7
+ import {
4
8
  computed,
5
9
  defineComponent,
6
10
  h,
7
11
  inject,
8
- InjectionKey,
9
- provide,
10
- Ref,
11
12
  onMounted,
12
13
  onUnmounted,
14
+ provide,
13
15
  reactive,
14
16
  ref
15
17
  } from 'vue'
@@ -25,12 +27,15 @@ const currentPageNum: InjectionKey<Ref<number>> = Symbol('home-page-num')
25
27
 
26
28
  const userWorks: InjectionKey<Ref<Theme.UserWorks>> = Symbol('user-works')
27
29
 
30
+ const homeFooter: InjectionKey<Theme.Footer | undefined> = Symbol('home-footer')
31
+
28
32
  export function withConfigProvider(App: Component) {
29
33
  return defineComponent({
30
34
  name: 'ConfigProvider',
31
35
  setup(_, { slots }) {
32
36
  const { theme } = useData()
33
37
  const config = computed(() => resolveConfig(theme.value))
38
+ provide(homeFooter, config.value.blog?.footer)
34
39
  provide(configSymbol, config)
35
40
  provide(
36
41
  userWorks,
@@ -119,7 +124,7 @@ export function useCurrentArticle() {
119
124
  ...[`${currentPath}index`, `${decodeURIComponent(currentPath)}index`]
120
125
  )
121
126
  }
122
- return docs.value?.find((v) => okPaths.includes(withBase(v.route)))
127
+ return docs.value?.find(v => okPaths.includes(withBase(v.route)))
123
128
  })
124
129
 
125
130
  return currentArticle
@@ -195,3 +200,7 @@ export function useAutoUpdateAnchor() {
195
200
  // 返回当前锚点的响应式对象
196
201
  return currentAnchor
197
202
  }
203
+
204
+ export function useHomeFooterConfig() {
205
+ return inject(homeFooter)
206
+ }