@sugarat/theme 0.2.29 → 0.2.30
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.
- package/node.d.ts +2 -1
- package/package.json +3 -3
- package/src/components/BlogApp.vue +0 -1
- package/src/components/BlogHomeTags.vue +5 -4
- package/src/components/BlogHotArticle.vue +11 -6
- package/src/components/BlogItem.vue +35 -17
- package/src/composables/config/index.ts +2 -1
- package/src/components/BlogSearch.vue +0 -419
- package/src/components/LogoPagefind.vue +0 -55
package/node.d.ts
CHANGED
|
@@ -308,7 +308,7 @@ declare namespace Theme {
|
|
|
308
308
|
pagesData: PageData[];
|
|
309
309
|
srcDir?: string;
|
|
310
310
|
author?: string;
|
|
311
|
-
hotArticle?: HotArticle;
|
|
311
|
+
hotArticle?: HotArticle | false;
|
|
312
312
|
home?: HomeBlog;
|
|
313
313
|
/**
|
|
314
314
|
* 本地全文搜索定制
|
|
@@ -390,6 +390,7 @@ declare namespace Theme {
|
|
|
390
390
|
* 详见 https://oml2d.com/options/Options.html
|
|
391
391
|
*/
|
|
392
392
|
oml2d?: Options;
|
|
393
|
+
homeTags?: boolean;
|
|
393
394
|
}
|
|
394
395
|
interface BackToTop {
|
|
395
396
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sugarat/theme",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.30",
|
|
4
4
|
"description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
|
|
5
5
|
"author": "sugar",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,11 +42,11 @@
|
|
|
42
42
|
"gray-matter": "^4.0.3",
|
|
43
43
|
"markdown-it-task-checkbox": "^1.0.6",
|
|
44
44
|
"mermaid": "^10.2.4",
|
|
45
|
-
"oh-my-live2d": "^0.
|
|
45
|
+
"oh-my-live2d": "^0.15.2",
|
|
46
46
|
"swiper": "^11.0.5",
|
|
47
47
|
"vitepress-markdown-timeline": "^1.2.1",
|
|
48
48
|
"vitepress-plugin-mermaid": "2.0.13",
|
|
49
|
-
"vitepress-plugin-pagefind": "0.2.
|
|
49
|
+
"vitepress-plugin-pagefind": "0.2.14",
|
|
50
50
|
"vitepress-plugin-rss": "0.2.2",
|
|
51
51
|
"vitepress-plugin-tabs": "0.2.0"
|
|
52
52
|
},
|
|
@@ -9,7 +9,6 @@ import BlogHomeBanner from './BlogHomeBanner.vue'
|
|
|
9
9
|
import BlogList from './BlogList.vue'
|
|
10
10
|
import BlogComment from './BlogComment.vue'
|
|
11
11
|
|
|
12
|
-
// import BlogSearch from './BlogSearch.vue'
|
|
13
12
|
import BlogSidebar from './BlogSidebar.vue'
|
|
14
13
|
import BlogImagePreview from './BlogImagePreview.vue'
|
|
15
14
|
import BlogArticleAnalyze from './BlogArticleAnalyze.vue'
|
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
import { computed, watch } from 'vue'
|
|
3
3
|
import { ElTag } from 'element-plus'
|
|
4
4
|
import { useBrowserLocation, useDark, useUrlSearchParams } from '@vueuse/core'
|
|
5
|
-
import {
|
|
5
|
+
import { useRoute, useRouter } from 'vitepress'
|
|
6
6
|
import {
|
|
7
7
|
useActiveTag,
|
|
8
8
|
useArticles,
|
|
9
|
-
|
|
9
|
+
useConfig,
|
|
10
|
+
useCurrentPageNum,
|
|
10
11
|
} from '../composables/config/blog'
|
|
11
12
|
|
|
12
13
|
const route = useRoute()
|
|
13
14
|
const docs = useArticles()
|
|
14
|
-
|
|
15
|
+
const showTags = useConfig()?.config?.blog?.homeTags ?? true
|
|
15
16
|
const tags = computed(() => {
|
|
16
17
|
return [...new Set(docs.value.map(v => v.meta.tag || []).flat(3))]
|
|
17
18
|
})
|
|
@@ -77,7 +78,7 @@ watch(
|
|
|
77
78
|
</script>
|
|
78
79
|
|
|
79
80
|
<template>
|
|
80
|
-
<div v-if="tags.length" class="card tags" data-pagefind-ignore="all">
|
|
81
|
+
<div v-if="showTags && tags.length" class="card tags" data-pagefind-ignore="all">
|
|
81
82
|
<!-- 头部 -->
|
|
82
83
|
<div class="card-header">
|
|
83
84
|
<span class="title svg-icon"><svg
|
|
@@ -6,11 +6,16 @@ import { useArticles, useBlogConfig, useCleanUrls } from '../composables/config/
|
|
|
6
6
|
import { formatShowDate, wrapperCleanUrls } from '../utils/client'
|
|
7
7
|
import { fireSVG } from '../constants/svg'
|
|
8
8
|
|
|
9
|
-
const { hotArticle } = useBlogConfig()
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
const { hotArticle: _hotArticle } = useBlogConfig()
|
|
10
|
+
|
|
11
|
+
const hotArticle = computed(() =>
|
|
12
|
+
_hotArticle === false ? undefined : _hotArticle
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
const title = computed(() => hotArticle.value?.title || (`<span class="svg-icon">${fireSVG}</span>` + ' 精选文章'))
|
|
16
|
+
const nextText = computed(() => hotArticle.value?.nextText || '换一组')
|
|
17
|
+
const pageSize = computed(() => hotArticle.value?.pageSize || 9)
|
|
18
|
+
const empty = computed(() => hotArticle.value?.empty ?? '暂无精选内容')
|
|
14
19
|
|
|
15
20
|
const docs = useArticles()
|
|
16
21
|
|
|
@@ -43,7 +48,7 @@ const showChangeBtn = computed(() => {
|
|
|
43
48
|
</script>
|
|
44
49
|
|
|
45
50
|
<template>
|
|
46
|
-
<div v-if="recommendList.length || empty" class="card recommend" data-pagefind-ignore="all">
|
|
51
|
+
<div v-if="_hotArticle !== false && (recommendList.length || empty) " class="card recommend" data-pagefind-ignore="all">
|
|
47
52
|
<!-- 头部 -->
|
|
48
53
|
<div class="card-header">
|
|
49
54
|
<span class="title" v-html="title" />
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import { withBase } from 'vitepress'
|
|
3
3
|
import { computed } from 'vue'
|
|
4
|
-
import { useWindowSize } from '@vueuse/core'
|
|
5
4
|
import { formatShowDate, wrapperCleanUrls } from '../utils/client'
|
|
6
5
|
import { useCleanUrls } from '../composables/config/blog'
|
|
7
6
|
|
|
@@ -17,8 +16,6 @@ const props = defineProps<{
|
|
|
17
16
|
cover?: string | boolean
|
|
18
17
|
pin?: number
|
|
19
18
|
}>()
|
|
20
|
-
const { width } = useWindowSize()
|
|
21
|
-
const inMobile = computed(() => width.value <= 500)
|
|
22
19
|
const showTime = computed(() => {
|
|
23
20
|
return formatShowDate(props.date)
|
|
24
21
|
})
|
|
@@ -28,15 +25,16 @@ const link = computed(() => withBase(wrapperCleanUrls(!!cleanUrls, props.route))
|
|
|
28
25
|
</script>
|
|
29
26
|
|
|
30
27
|
<template>
|
|
28
|
+
<!-- TODO: 响应式优化使用纯 CSS -->
|
|
31
29
|
<a class="blog-item" :href="link">
|
|
32
30
|
<i v-if="!!pin" class="pin" />
|
|
33
31
|
<!-- 标题 -->
|
|
34
|
-
<p
|
|
32
|
+
<p class="title mobile-visible">{{ title }}</p>
|
|
35
33
|
<div class="info-container">
|
|
36
34
|
<!-- 左侧信息 -->
|
|
37
35
|
<div class="info-part">
|
|
38
36
|
<!-- 标题 -->
|
|
39
|
-
<p
|
|
37
|
+
<p class="title pc-visible">{{ title }}</p>
|
|
40
38
|
<!-- 简短描述 -->
|
|
41
39
|
<p v-if="!descriptionHTML && !!description" class="description">
|
|
42
40
|
{{ description }}
|
|
@@ -45,21 +43,17 @@ const link = computed(() => withBase(wrapperCleanUrls(!!cleanUrls, props.route))
|
|
|
45
43
|
<div class="description-html" v-html="descriptionHTML" />
|
|
46
44
|
</template>
|
|
47
45
|
<!-- 底部补充描述 -->
|
|
48
|
-
<div
|
|
46
|
+
<div class="badge-list pc-visible">
|
|
49
47
|
<span v-if="author" class="split">{{ author }}</span>
|
|
50
48
|
<span class="split">{{ showTime }}</span>
|
|
51
49
|
<span v-if="tag?.length" class="split">{{ tag.join(' · ') }}</span>
|
|
52
50
|
</div>
|
|
53
51
|
</div>
|
|
54
52
|
<!-- 右侧封面图 -->
|
|
55
|
-
<div
|
|
56
|
-
v-if="cover"
|
|
57
|
-
class="cover-img"
|
|
58
|
-
:style="`background-image: url(${withBase(`${cover}`)});`"
|
|
59
|
-
/>
|
|
53
|
+
<div v-if="cover" class="cover-img" :style="`background-image: url(${withBase(`${cover}`)});`" />
|
|
60
54
|
</div>
|
|
61
55
|
<!-- 底部补充描述 -->
|
|
62
|
-
<div
|
|
56
|
+
<div class="badge-list mobile-visible">
|
|
63
57
|
<span v-if="author" class="split">{{ author }}</span>
|
|
64
58
|
<span class="split">{{ showTime }}</span>
|
|
65
59
|
<span v-if="tag?.length" class="split">{{ tag.join(' · ') }}</span>
|
|
@@ -77,19 +71,19 @@ const link = computed(() => withBase(wrapperCleanUrls(!!cleanUrls, props.route))
|
|
|
77
71
|
left: -4px;
|
|
78
72
|
opacity: 0.5;
|
|
79
73
|
}
|
|
74
|
+
|
|
80
75
|
.blog-item:hover .pin {
|
|
81
76
|
opacity: 1;
|
|
82
77
|
}
|
|
78
|
+
|
|
83
79
|
.blog-item .pin::before {
|
|
84
80
|
content: '';
|
|
85
81
|
position: absolute;
|
|
86
82
|
width: 120%;
|
|
87
83
|
height: 30px;
|
|
88
|
-
background-image: linear-gradient(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
var(--blog-theme-color)
|
|
92
|
-
);
|
|
84
|
+
background-image: linear-gradient(45deg,
|
|
85
|
+
var(--blog-theme-color),
|
|
86
|
+
var(--blog-theme-color));
|
|
93
87
|
transform: rotate(-45deg) translateY(-20px);
|
|
94
88
|
display: flex;
|
|
95
89
|
align-items: center;
|
|
@@ -111,10 +105,12 @@ const link = computed(() => withBase(wrapperCleanUrls(!!cleanUrls, props.route))
|
|
|
111
105
|
cursor: pointer;
|
|
112
106
|
display: flex;
|
|
113
107
|
flex-direction: column;
|
|
108
|
+
|
|
114
109
|
&:hover {
|
|
115
110
|
box-shadow: var(--box-shadow-hover);
|
|
116
111
|
}
|
|
117
112
|
}
|
|
113
|
+
|
|
118
114
|
.info-container {
|
|
119
115
|
display: flex;
|
|
120
116
|
align-items: center;
|
|
@@ -124,11 +120,13 @@ const link = computed(() => withBase(wrapperCleanUrls(!!cleanUrls, props.route))
|
|
|
124
120
|
.info-part {
|
|
125
121
|
flex: 1;
|
|
126
122
|
}
|
|
123
|
+
|
|
127
124
|
.title {
|
|
128
125
|
font-size: 18px;
|
|
129
126
|
font-weight: 600;
|
|
130
127
|
margin-bottom: 8px;
|
|
131
128
|
}
|
|
129
|
+
|
|
132
130
|
.description {
|
|
133
131
|
color: var(--description-font-color);
|
|
134
132
|
font-size: 14px;
|
|
@@ -140,13 +138,16 @@ const link = computed(() => withBase(wrapperCleanUrls(!!cleanUrls, props.route))
|
|
|
140
138
|
-webkit-line-clamp: 2;
|
|
141
139
|
-webkit-box-orient: vertical;
|
|
142
140
|
}
|
|
141
|
+
|
|
143
142
|
.description-html {
|
|
144
143
|
font-size: 14px;
|
|
145
144
|
}
|
|
145
|
+
|
|
146
146
|
.badge-list {
|
|
147
147
|
font-size: 13px;
|
|
148
148
|
color: var(--badge-font-color);
|
|
149
149
|
margin-top: 8px;
|
|
150
|
+
|
|
150
151
|
.split:not(:last-child) {
|
|
151
152
|
&::after {
|
|
152
153
|
content: '';
|
|
@@ -158,6 +159,7 @@ const link = computed(() => withBase(wrapperCleanUrls(!!cleanUrls, props.route))
|
|
|
158
159
|
}
|
|
159
160
|
}
|
|
160
161
|
}
|
|
162
|
+
|
|
161
163
|
.cover-img {
|
|
162
164
|
width: 120px;
|
|
163
165
|
height: 80px;
|
|
@@ -167,11 +169,27 @@ const link = computed(() => withBase(wrapperCleanUrls(!!cleanUrls, props.route))
|
|
|
167
169
|
background-size: 120px 80px;
|
|
168
170
|
}
|
|
169
171
|
|
|
172
|
+
.pc-visible {
|
|
173
|
+
display: block;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.mobile-visible {
|
|
177
|
+
display: none;
|
|
178
|
+
}
|
|
179
|
+
|
|
170
180
|
@media screen and (max-width: 500px) {
|
|
171
181
|
.cover-img {
|
|
172
182
|
width: 100px;
|
|
173
183
|
height: 60px;
|
|
174
184
|
background-size: 100px 60px;
|
|
175
185
|
}
|
|
186
|
+
|
|
187
|
+
.pc-visible {
|
|
188
|
+
display: none;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.mobile-visible {
|
|
192
|
+
display: block;
|
|
193
|
+
}
|
|
176
194
|
}
|
|
177
195
|
</style>
|
|
@@ -340,7 +340,7 @@ export namespace Theme {
|
|
|
340
340
|
pagesData: PageData[]
|
|
341
341
|
srcDir?: string
|
|
342
342
|
author?: string
|
|
343
|
-
hotArticle?: HotArticle
|
|
343
|
+
hotArticle?: HotArticle | false
|
|
344
344
|
home?: HomeBlog
|
|
345
345
|
/**
|
|
346
346
|
* 本地全文搜索定制
|
|
@@ -423,6 +423,7 @@ export namespace Theme {
|
|
|
423
423
|
* 详见 https://oml2d.com/options/Options.html
|
|
424
424
|
*/
|
|
425
425
|
oml2d?: Oml2dOptions
|
|
426
|
+
homeTags?: boolean
|
|
426
427
|
}
|
|
427
428
|
|
|
428
429
|
export interface BackToTop {
|
|
@@ -1,419 +0,0 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
// @ts-nocheck
|
|
3
|
-
import { computed, nextTick, onBeforeMount, onMounted, ref, watch } from 'vue'
|
|
4
|
-
import { Command } from 'vue-command-palette'
|
|
5
|
-
import { useRoute, useRouter, withBase } from 'vitepress'
|
|
6
|
-
import { useMagicKeys, useWindowSize } from '@vueuse/core'
|
|
7
|
-
import { chineseSearchOptimize, formatDate } from '../utils/client'
|
|
8
|
-
import { useArticles, useBlogConfig } from '../composables/config/blog'
|
|
9
|
-
import type { Theme } from '../composables/config'
|
|
10
|
-
import LogoPagefind from './LogoPagefind.vue'
|
|
11
|
-
|
|
12
|
-
const searchResult = ref<Theme.PageData[]>([])
|
|
13
|
-
|
|
14
|
-
const windowSize = useWindowSize()
|
|
15
|
-
|
|
16
|
-
const isMinimized = computed(() => windowSize.width.value < 760)
|
|
17
|
-
const flexValue = computed(() => (isMinimized.value ? 0 : 1))
|
|
18
|
-
const { search: searchConfig } = useBlogConfig()
|
|
19
|
-
|
|
20
|
-
const headingText = computed(() => {
|
|
21
|
-
return searchConfig?.heading
|
|
22
|
-
? searchConfig.heading.replace(
|
|
23
|
-
/\{\{searchResult\}\}/,
|
|
24
|
-
searchResult.value.length
|
|
25
|
-
)
|
|
26
|
-
: `共: ${searchResult.value.length} 个搜索结果`
|
|
27
|
-
})
|
|
28
|
-
const openSearch = computed(() =>
|
|
29
|
-
searchConfig instanceof Object
|
|
30
|
-
? searchConfig.mode ?? true
|
|
31
|
-
: searchConfig ?? true
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
function addInlineScript() {
|
|
35
|
-
const scriptText = `import('${withBase('/_pagefind/pagefind.js')}')
|
|
36
|
-
.then((module) => {
|
|
37
|
-
window.__pagefind__ = module
|
|
38
|
-
})
|
|
39
|
-
.catch(() => {
|
|
40
|
-
console.log('not load /_pagefind/pagefind.js')
|
|
41
|
-
})`
|
|
42
|
-
const inlineScript = document.createElement('script')
|
|
43
|
-
inlineScript.innerHTML = scriptText
|
|
44
|
-
document.head.appendChild(inlineScript)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
onBeforeMount(() => {
|
|
48
|
-
if (openSearch.value === 'pagefind') {
|
|
49
|
-
addInlineScript()
|
|
50
|
-
}
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
const metaKey = ref('')
|
|
54
|
-
onMounted(() => {
|
|
55
|
-
metaKey.value = /(Mac|iPhone|iPod|iPad)/i.test(navigator?.platform)
|
|
56
|
-
? '⌘'
|
|
57
|
-
: 'Ctrl'
|
|
58
|
-
})
|
|
59
|
-
const searchModal = ref(false)
|
|
60
|
-
const searchWords = ref('')
|
|
61
|
-
const docs = useArticles()
|
|
62
|
-
const docsMap = computed(() => {
|
|
63
|
-
const map = new Map<string, Theme.PageData.meta>()
|
|
64
|
-
docs.value.forEach((doc) => {
|
|
65
|
-
map.set(withBase(doc.route.replace(/index$/, '')), doc.meta)
|
|
66
|
-
})
|
|
67
|
-
return map
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
const keys = useMagicKeys({
|
|
71
|
-
passive: false,
|
|
72
|
-
onEventFired(e) {
|
|
73
|
-
if (e.ctrlKey && e.key === 'k' && e.type === 'keydown')
|
|
74
|
-
e.preventDefault()
|
|
75
|
-
}
|
|
76
|
-
})
|
|
77
|
-
const CmdK = keys['Meta+K']
|
|
78
|
-
const CtrlK = keys['Ctrl+K']
|
|
79
|
-
// eslint-disable-next-line dot-notation, prefer-destructuring
|
|
80
|
-
const Escape = keys['Escape']
|
|
81
|
-
|
|
82
|
-
watch(CtrlK, (v) => {
|
|
83
|
-
if (v) {
|
|
84
|
-
searchModal.value = true
|
|
85
|
-
}
|
|
86
|
-
})
|
|
87
|
-
watch(CmdK, (v) => {
|
|
88
|
-
if (v) {
|
|
89
|
-
searchModal.value = true
|
|
90
|
-
}
|
|
91
|
-
})
|
|
92
|
-
watch(Escape, (v) => {
|
|
93
|
-
if (v) {
|
|
94
|
-
searchModal.value = false
|
|
95
|
-
}
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
function inlineSearch() {
|
|
99
|
-
if (!searchWords.value) {
|
|
100
|
-
searchResult.value = []
|
|
101
|
-
return
|
|
102
|
-
}
|
|
103
|
-
searchResult.value = docs.value
|
|
104
|
-
.filter(v =>
|
|
105
|
-
`${v.meta.description}${v.meta.title}`.includes(searchWords.value)
|
|
106
|
-
)
|
|
107
|
-
.map((v) => {
|
|
108
|
-
return {
|
|
109
|
-
...v,
|
|
110
|
-
meta: {
|
|
111
|
-
...v.meta,
|
|
112
|
-
description:
|
|
113
|
-
v.meta?.description?.replace(
|
|
114
|
-
new RegExp(`(${searchWords.value})`, 'g'),
|
|
115
|
-
'<mark>$1</mark>'
|
|
116
|
-
) || ''
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
})
|
|
120
|
-
searchResult.value.sort((a, b) => {
|
|
121
|
-
return +new Date(b.meta.date) - +new Date(a.meta.date)
|
|
122
|
-
})
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
watch(
|
|
126
|
-
() => searchWords.value,
|
|
127
|
-
async () => {
|
|
128
|
-
if (openSearch.value === 'pagefind') {
|
|
129
|
-
// dev-server兜底
|
|
130
|
-
// @ts-expect-error
|
|
131
|
-
if (!window?.__pagefind__?.search) {
|
|
132
|
-
inlineSearch()
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
// @ts-expect-error
|
|
136
|
-
await window?.__pagefind__
|
|
137
|
-
?.search?.(chineseSearchOptimize(searchWords.value))
|
|
138
|
-
.then(async (search: any) => {
|
|
139
|
-
const result = await Promise.all(
|
|
140
|
-
search.results.map((v: any) => v.data())
|
|
141
|
-
)
|
|
142
|
-
searchResult.value = result.map((result) => {
|
|
143
|
-
const { url, excerpt } = result
|
|
144
|
-
const targetRoute = url.replace(/\.html$/, '')
|
|
145
|
-
const meta = docsMap.value.get(targetRoute)
|
|
146
|
-
if (meta) {
|
|
147
|
-
return {
|
|
148
|
-
route: targetRoute,
|
|
149
|
-
meta: {
|
|
150
|
-
...meta,
|
|
151
|
-
description: excerpt
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return {
|
|
156
|
-
route: url,
|
|
157
|
-
meta: {
|
|
158
|
-
...result.meta,
|
|
159
|
-
description: excerpt
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
})
|
|
163
|
-
})
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
inlineSearch()
|
|
168
|
-
}
|
|
169
|
-
nextTick(() => {
|
|
170
|
-
// hack 原组件实现
|
|
171
|
-
document.querySelectorAll('div[aria-disabled="true"]').forEach((v) => {
|
|
172
|
-
v.setAttribute('aria-disabled', 'false')
|
|
173
|
-
})
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
function handleClickMask(e: any) {
|
|
179
|
-
if (e.target === e.currentTarget) {
|
|
180
|
-
searchModal.value = false
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
watch(
|
|
184
|
-
() => searchModal.value,
|
|
185
|
-
(newValue) => {
|
|
186
|
-
if (newValue) {
|
|
187
|
-
nextTick(() => {
|
|
188
|
-
document
|
|
189
|
-
.querySelector('div[command-dialog-mask]')
|
|
190
|
-
?.addEventListener('click', handleClickMask)
|
|
191
|
-
})
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
document
|
|
195
|
-
.querySelector('div[command-dialog-mask]')
|
|
196
|
-
?.removeEventListener('click', handleClickMask)
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
// 搜索结果分页?
|
|
202
|
-
// const pageSize = ref(6)
|
|
203
|
-
// const currentPage = ref(0)
|
|
204
|
-
// const showSearchResult = computed(() => {
|
|
205
|
-
// // 合法性处理
|
|
206
|
-
// const pageIdx =
|
|
207
|
-
// currentPage.value % Math.ceil(searchResult.value.length / pageSize.value)
|
|
208
|
-
// const startIdx = pageIdx * pageSize.value
|
|
209
|
-
// return searchResult.value.slice(startIdx, startIdx + pageSize.value)
|
|
210
|
-
// })
|
|
211
|
-
|
|
212
|
-
const router = useRouter()
|
|
213
|
-
const route = useRoute()
|
|
214
|
-
function handleSelect(target: any) {
|
|
215
|
-
searchModal.value = false
|
|
216
|
-
if (!route.path.startsWith(target.value)) {
|
|
217
|
-
// searchWords.value = ''
|
|
218
|
-
router.go(target.value)
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
</script>
|
|
222
|
-
|
|
223
|
-
<template>
|
|
224
|
-
<div v-if="openSearch" class="blog-search" data-pagefind-ignore="all">
|
|
225
|
-
<div class="nav-search-btn-wait" @click="searchModal = true">
|
|
226
|
-
<svg width="14" height="14" viewBox="0 0 20 20">
|
|
227
|
-
<path
|
|
228
|
-
d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
|
|
229
|
-
stroke="currentColor"
|
|
230
|
-
fill="none"
|
|
231
|
-
fill-rule="evenodd"
|
|
232
|
-
stroke-linecap="round"
|
|
233
|
-
stroke-linejoin="round"
|
|
234
|
-
/>
|
|
235
|
-
</svg>
|
|
236
|
-
<span v-if="!isMinimized" class="search-tip">{{
|
|
237
|
-
searchConfig?.btnPlaceholder || '搜索'
|
|
238
|
-
}}</span>
|
|
239
|
-
<span v-if="!isMinimized" class="metaKey"> {{ metaKey }} K </span>
|
|
240
|
-
</div>
|
|
241
|
-
<Command.Dialog :visible="searchModal" theme="algolia">
|
|
242
|
-
<template #header>
|
|
243
|
-
<Command.Input
|
|
244
|
-
v-model:value="searchWords"
|
|
245
|
-
:placeholder="searchConfig?.placeholder || '请输入要搜素的内容'"
|
|
246
|
-
/>
|
|
247
|
-
</template>
|
|
248
|
-
<template #body>
|
|
249
|
-
<div class="search-dialog">
|
|
250
|
-
<Command.List>
|
|
251
|
-
<Command.Empty v-if="!searchResult.length">
|
|
252
|
-
{{
|
|
253
|
-
searchConfig?.emptyText || 'No results found.'
|
|
254
|
-
}}
|
|
255
|
-
</Command.Empty>
|
|
256
|
-
<Command.Group v-else :heading="headingText">
|
|
257
|
-
<Command.Item
|
|
258
|
-
v-for="item in searchResult"
|
|
259
|
-
:key="item.route"
|
|
260
|
-
:data-value="item.route"
|
|
261
|
-
@select="handleSelect"
|
|
262
|
-
>
|
|
263
|
-
<div class="link">
|
|
264
|
-
<div class="title">
|
|
265
|
-
<span>{{ item.meta.title }}</span>
|
|
266
|
-
<span class="date">
|
|
267
|
-
{{ formatDate(item.meta.date, 'yyyy-MM-dd') }}</span>
|
|
268
|
-
</div>
|
|
269
|
-
<div class="des" v-html="item.meta.description" />
|
|
270
|
-
</div>
|
|
271
|
-
</Command.Item>
|
|
272
|
-
</Command.Group>
|
|
273
|
-
</Command.List>
|
|
274
|
-
</div>
|
|
275
|
-
</template>
|
|
276
|
-
<template v-if="searchResult.length" #footer>
|
|
277
|
-
<div class="command-palette-logo">
|
|
278
|
-
<a
|
|
279
|
-
v-if="openSearch === 'pagefind'"
|
|
280
|
-
href="https://github.com/cloudcannon/pagefind"
|
|
281
|
-
target="_blank"
|
|
282
|
-
rel="noopener noreferrer"
|
|
283
|
-
>
|
|
284
|
-
<span class="command-palette-Label">Search by</span>
|
|
285
|
-
<LogoPagefind style="width: 77px" />
|
|
286
|
-
</a>
|
|
287
|
-
</div>
|
|
288
|
-
<ul class="command-palette-commands">
|
|
289
|
-
<li>
|
|
290
|
-
<kbd class="command-palette-commands-key"><svg width="15" height="15" aria-label="Enter key" role="img">
|
|
291
|
-
<g
|
|
292
|
-
fill="none"
|
|
293
|
-
stroke="currentColor"
|
|
294
|
-
stroke-linecap="round"
|
|
295
|
-
stroke-linejoin="round"
|
|
296
|
-
stroke-width="1.2"
|
|
297
|
-
>
|
|
298
|
-
<path
|
|
299
|
-
d="M12 3.53088v3c0 1-1 2-2 2H4M7 11.53088l-3-3 3-3"
|
|
300
|
-
/>
|
|
301
|
-
</g></svg></kbd><span class="command-palette-Label">to select</span>
|
|
302
|
-
</li>
|
|
303
|
-
<li>
|
|
304
|
-
<kbd class="command-palette-commands-key"><svg width="15" height="15" aria-label="Arrow down" role="img">
|
|
305
|
-
<g
|
|
306
|
-
fill="none"
|
|
307
|
-
stroke="currentColor"
|
|
308
|
-
stroke-linecap="round"
|
|
309
|
-
stroke-linejoin="round"
|
|
310
|
-
stroke-width="1.2"
|
|
311
|
-
>
|
|
312
|
-
<path d="M7.5 3.5v8M10.5 8.5l-3 3-3-3" />
|
|
313
|
-
</g></svg></kbd><kbd class="command-palette-commands-key"><svg width="15" height="15" aria-label="Arrow up" role="img">
|
|
314
|
-
<g
|
|
315
|
-
fill="none"
|
|
316
|
-
stroke="currentColor"
|
|
317
|
-
stroke-linecap="round"
|
|
318
|
-
stroke-linejoin="round"
|
|
319
|
-
stroke-width="1.2"
|
|
320
|
-
>
|
|
321
|
-
<path d="M7.5 11.5v-8M10.5 6.5l-3-3-3 3" />
|
|
322
|
-
</g></svg></kbd><span class="command-palette-Label">to navigate</span>
|
|
323
|
-
</li>
|
|
324
|
-
<li>
|
|
325
|
-
<kbd class="command-palette-commands-key"><svg width="15" height="15" aria-label="Escape key" role="img">
|
|
326
|
-
<g
|
|
327
|
-
fill="none"
|
|
328
|
-
stroke="currentColor"
|
|
329
|
-
stroke-linecap="round"
|
|
330
|
-
stroke-linejoin="round"
|
|
331
|
-
stroke-width="1.2"
|
|
332
|
-
>
|
|
333
|
-
<path
|
|
334
|
-
d="M13.6167 8.936c-.1065.3583-.6883.962-1.4875.962-.7993 0-1.653-.9165-1.653-2.1258v-.5678c0-1.2548.7896-2.1016 1.653-2.1016.8634 0 1.3601.4778 1.4875 1.0724M9 6c-.1352-.4735-.7506-.9219-1.46-.8972-.7092.0246-1.344.57-1.344 1.2166s.4198.8812 1.3445.9805C8.465 7.3992 8.968 7.9337 9 8.5c.032.5663-.454 1.398-1.4595 1.398C6.6593 9.898 6 9 5.963 8.4851m-1.4748.5368c-.2635.5941-.8099.876-1.5443.876s-1.7073-.6248-1.7073-2.204v-.4603c0-1.0416.721-2.131 1.7073-2.131.9864 0 1.6425 1.031 1.5443 2.2492h-2.956"
|
|
335
|
-
/>
|
|
336
|
-
</g></svg></kbd><span class="command-palette-Label">to close</span>
|
|
337
|
-
</li>
|
|
338
|
-
</ul>
|
|
339
|
-
</template>
|
|
340
|
-
</Command.Dialog>
|
|
341
|
-
</div>
|
|
342
|
-
</template>
|
|
343
|
-
|
|
344
|
-
<style lang="scss" scoped>
|
|
345
|
-
.blog-search {
|
|
346
|
-
flex: v-bind(flexValue);
|
|
347
|
-
display: flex;
|
|
348
|
-
padding-left: 32px;
|
|
349
|
-
.nav-search-btn-wait {
|
|
350
|
-
cursor: pointer;
|
|
351
|
-
display: flex;
|
|
352
|
-
align-items: center;
|
|
353
|
-
justify-content: center;
|
|
354
|
-
padding: 6px;
|
|
355
|
-
box-sizing: border-box;
|
|
356
|
-
border: 1px solid transparent;
|
|
357
|
-
border-radius: 6px;
|
|
358
|
-
transition: .2s border;
|
|
359
|
-
|
|
360
|
-
.metaKey {
|
|
361
|
-
margin-left: 10px;
|
|
362
|
-
font-size: 12px;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
&:hover {
|
|
366
|
-
border: 1px solid var(--vp-c-brand-1);
|
|
367
|
-
border-radius: 6px;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
.search-tip {
|
|
371
|
-
color: #909399;
|
|
372
|
-
font-size: 12px;
|
|
373
|
-
padding-left: 10px;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
</style>
|
|
378
|
-
|
|
379
|
-
<style lang="scss">
|
|
380
|
-
@import '../styles/scss/global.scss';
|
|
381
|
-
@import '../styles/scss/algolia.scss';
|
|
382
|
-
|
|
383
|
-
div[command-group] {
|
|
384
|
-
display: block !important;
|
|
385
|
-
}
|
|
386
|
-
div[command-item] {
|
|
387
|
-
display: flex !important;
|
|
388
|
-
}
|
|
389
|
-
.search-dialog {
|
|
390
|
-
div[command-item] > div.link {
|
|
391
|
-
width: 100%;
|
|
392
|
-
}
|
|
393
|
-
div[command-item] .title {
|
|
394
|
-
display: flex;
|
|
395
|
-
justify-content: space-between;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
div[command-item] .des {
|
|
399
|
-
text-overflow: ellipsis;
|
|
400
|
-
overflow: hidden;
|
|
401
|
-
word-break: keep-all;
|
|
402
|
-
white-space: nowrap;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
div[command-item] .date {
|
|
406
|
-
min-width: 80px;
|
|
407
|
-
}
|
|
408
|
-
div[command-item] mark {
|
|
409
|
-
background: none;
|
|
410
|
-
color: var(--vp-c-brand-1);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
div[command-item][aria-selected='true'] mark,
|
|
414
|
-
div[command-item]:hover mark {
|
|
415
|
-
color: inherit;
|
|
416
|
-
text-decoration: underline;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
</style>
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<svg
|
|
3
|
-
width="594"
|
|
4
|
-
height="112"
|
|
5
|
-
viewBox="0 0 594 112"
|
|
6
|
-
fill="none"
|
|
7
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
8
|
-
>
|
|
9
|
-
<path
|
|
10
|
-
d="M147.8 111.2H164V77.5998H164.6C164.6 77.5998 170.6 87.1998 183.2 87.1998C197 87.1998 209.6 74.5998 209.6 56.5998C209.6 38.5998 197 25.9998 183.2 25.9998C170.6 25.9998 164.6 35.5998 164.6 35.5998H164V27.1998H147.8V111.2ZM178.4 72.1998C170 72.1998 163.4 65.5998 163.4 56.5998C163.4 47.5998 170 40.9998 178.4 40.9998C186.8 40.9998 193.4 47.5998 193.4 56.5998C193.4 65.5998 186.8 72.1998 178.4 72.1998Z"
|
|
11
|
-
fill="black"
|
|
12
|
-
/>
|
|
13
|
-
<path
|
|
14
|
-
d="M230.628 87.1998C242.028 87.1998 248.028 78.7998 248.028 78.7998H248.628V85.9998C252.228 85.9998 264.828 85.9998 264.828 85.9998V49.3998C264.828 36.1998 254.628 25.9998 239.628 25.9998C224.028 25.9998 215.628 37.3998 215.628 37.3998L225.228 46.9998C225.228 46.9998 230.028 40.3998 238.428 40.3998C244.428 40.3998 248.028 43.9998 248.628 48.1998L230.028 51.5598C219.228 53.4798 212.628 60.7998 212.628 70.3998C212.628 79.9998 219.828 87.1998 230.628 87.1998ZM236.028 73.9998C231.228 73.9998 228.828 71.5998 228.828 67.9998C228.828 64.9998 231.228 62.7198 235.428 61.9998L248.628 59.5998V60.7998C248.628 68.5998 243.228 73.9998 236.028 73.9998Z"
|
|
15
|
-
fill="black"
|
|
16
|
-
/>
|
|
17
|
-
<path
|
|
18
|
-
d="M299.033 111.2C317.633 111.2 330.833 97.9998 330.833 79.9998V27.1998H314.633V35.5998H314.033C314.033 35.5998 308.633 25.9998 296.033 25.9998C282.833 25.9998 270.833 37.9998 270.833 55.3998C270.833 72.7998 282.833 84.7998 296.033 84.7998C308.633 84.7998 314.033 75.1998 314.033 75.1998H314.633V79.9998C314.633 89.5998 308.033 96.1998 299.033 96.1998C289.433 96.1998 283.433 88.9998 283.433 88.9998L273.233 99.1998C273.233 99.1998 281.633 111.2 299.033 111.2ZM300.833 69.7998C293.033 69.7998 287.033 63.7998 287.033 55.3998C287.033 46.9998 293.033 40.9998 300.833 40.9998C308.633 40.9998 314.633 46.9998 314.633 55.3998C314.633 63.7998 308.633 69.7998 300.833 69.7998Z"
|
|
19
|
-
fill="black"
|
|
20
|
-
/>
|
|
21
|
-
<path
|
|
22
|
-
d="M367.986 87.1998C384.186 87.1998 393.186 77.5998 393.186 77.5998L384.786 66.1998C384.786 66.1998 379.386 72.7998 369.186 72.7998C360.186 72.7998 355.386 67.9998 353.586 62.5998H396.186C396.186 62.5998 396.786 59.5998 396.786 55.3998C396.786 39.1998 383.586 25.9998 367.386 25.9998C350.586 25.9998 336.786 39.7998 336.786 56.5998C336.786 73.3998 350.586 87.1998 367.986 87.1998ZM353.586 50.5998C355.386 45.1998 360.186 40.3998 366.786 40.3998C373.386 40.3998 378.186 45.1998 379.986 50.5998H353.586Z"
|
|
23
|
-
fill="black"
|
|
24
|
-
/>
|
|
25
|
-
<path
|
|
26
|
-
d="M406.423 85.9998H422.624V43.3998H444.224V85.9998H460.423V28.3998H422.624V24.7998C422.624 19.3998 425.624 16.3998 430.423 16.3998C433.423 16.3998 435.823 17.5998 435.823 17.5998V2.5998C435.823 2.5998 431.624 0.799805 426.224 0.799805C414.224 0.799805 406.423 8.59981 406.423 22.3998V28.3998H397.423V43.3998H406.423V85.9998ZM452.263 19.3998C457.423 19.3998 461.624 15.1998 461.624 10.3998C461.624 5.59981 457.424 1.3998 452.384 1.3998C447.224 1.3998 443.023 5.59981 443.023 10.3998C443.023 15.1998 447.223 19.3998 452.263 19.3998Z"
|
|
27
|
-
fill="black"
|
|
28
|
-
/>
|
|
29
|
-
<path
|
|
30
|
-
d="M470.652 85.9998H486.852V54.7998C486.852 46.9998 492.252 41.5998 499.452 41.5998C506.052 41.5998 510.252 45.7998 510.252 52.9998V85.9998H526.452V50.5998C526.452 35.5998 516.852 25.9998 504.852 25.9998C493.452 25.9998 487.452 35.5998 487.452 35.5998H486.852V27.1998H470.652V85.9998Z"
|
|
31
|
-
fill="black"
|
|
32
|
-
/>
|
|
33
|
-
<path
|
|
34
|
-
d="M557.819 87.1998C570.419 87.1998 576.419 77.5998 576.419 77.5998H577.019V85.9998H593.219V1.9998H577.019V35.5998H576.419C576.419 35.5998 570.419 25.9998 557.819 25.9998C544.019 25.9998 531.419 38.5998 531.419 56.5998C531.419 74.5998 544.019 87.1998 557.819 87.1998ZM562.619 72.1998C554.219 72.1998 547.619 65.5998 547.619 56.5998C547.619 47.5998 554.219 40.9998 562.619 40.9998C571.019 40.9998 577.619 47.5998 577.619 56.5998C577.619 65.5998 571.019 72.1998 562.619 72.1998Z"
|
|
35
|
-
fill="black"
|
|
36
|
-
/>
|
|
37
|
-
<path
|
|
38
|
-
fill-rule="evenodd"
|
|
39
|
-
clip-rule="evenodd"
|
|
40
|
-
d="M60 96.9999C93.1371 96.9999 120 81.8416 120 63.1428V50.8311H115.91C107.182 38.2198 85.4398 29.2856 60 29.2856C34.5602 29.2856 12.8183 38.2198 4.09026 50.8311H0V63.1428C0 81.8416 26.8629 96.9999 60 96.9999Z"
|
|
41
|
-
fill="black"
|
|
42
|
-
/>
|
|
43
|
-
<path
|
|
44
|
-
d="M116 52C116 59.317 110.727 66.7404 100.454 72.5615C90.3014 78.3149 76.0069 82 60 82C43.9931 82 29.6986 78.3149 19.5456 72.5615C9.2731 66.7404 4 59.317 4 52C4 44.6831 9.2731 37.2596 19.5456 31.4385C29.6986 25.6851 43.9931 22 60 22C76.0069 22 90.3014 25.6851 100.454 31.4385C110.727 37.2596 116 44.6831 116 52Z"
|
|
45
|
-
fill="white"
|
|
46
|
-
stroke="black"
|
|
47
|
-
stroke-width="8"
|
|
48
|
-
/>
|
|
49
|
-
<path
|
|
50
|
-
d="M57.8864 72.0605L87.2817 41.837C88.6253 40.4556 87.43 38.1599 85.5278 38.4684L26.0819 48.1083C23.9864 48.4481 23.794 51.3882 25.8273 51.9982L46.7151 58.2645C47.2181 58.4154 47.6415 58.7581 47.894 59.2185L54.6991 71.6277C55.3457 72.8069 56.9487 73.0246 57.8864 72.0605Z"
|
|
51
|
-
fill="black"
|
|
52
|
-
/>
|
|
53
|
-
<ellipse cx="58" cy="53.5" rx="7" ry="4.5" fill="white" />
|
|
54
|
-
</svg>
|
|
55
|
-
</template>
|