Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Tc.小浩
unidocs-zh
提交
36027151
U
unidocs-zh
项目概览
Tc.小浩
/
unidocs-zh
与 Fork 源项目一致
Fork自
DCloud / unidocs-zh
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
unidocs-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
36027151
编写于
3月 17, 2022
作者:
D
DCloud_LXH
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
wip: searchPgae
上级
9f70e132
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
415 addition
and
25 deletion
+415
-25
docs/.vuepress/theme/components/DcloudSearchPage/index.vue
docs/.vuepress/theme/components/DcloudSearchPage/index.vue
+242
-0
docs/.vuepress/theme/components/DcloudSearchPage/searchClient.js
...uepress/theme/components/DcloudSearchPage/searchClient.js
+96
-0
docs/.vuepress/theme/components/Navbar.vue
docs/.vuepress/theme/components/Navbar.vue
+4
-24
docs/.vuepress/theme/components/NavbarLogo.vue
docs/.vuepress/theme/components/NavbarLogo.vue
+24
-0
docs/.vuepress/theme/layouts/Layout.vue
docs/.vuepress/theme/layouts/Layout.vue
+8
-1
docs/.vuepress/theme/util/index.js
docs/.vuepress/theme/util/index.js
+2
-0
docs/.vuepress/theme/util/searchUtils.js
docs/.vuepress/theme/util/searchUtils.js
+39
-0
未找到文件。
docs/.vuepress/theme/components/DcloudSearchPage/index.vue
0 → 100644
浏览文件 @
36027151
<
template
>
<div
id=
"search-container"
>
<div
class=
"search-navbar"
>
<div
class=
"search-navbar-wrap"
>
<div
class=
"search-navbar-header navbar"
>
<div
class=
"main-navbar"
>
<NavbarLogo
/>
<div
class=
"main-navbar-links can-hide"
>
<div
class=
"main-navbar-item active"
></div>
</div>
</div>
<div
class=
"sub-navbar"
>
<div
class=
"search-wrap"
>
<div
class=
"input-wrap"
>
<input
class=
"search-input"
:placeholder=
"placeholder"
type=
"text"
v-model=
"searchValue"
/>
<span
class=
"search-input-btn"
>
<button
@
click=
"search"
>
<svg
width=
"16"
height=
"16"
viewBox=
"0 0 16 16"
xmlns=
"http://www.w3.org/2000/svg"
>
<path
d=
"M11.33 10.007l4.273 4.273a.502.502 0 0 1 .005.709l-.585.584a.499.499 0 0 1-.709-.004L10.046 11.3a6.278 6.278 0 1 1 1.284-1.294zm.012-3.729a5.063 5.063 0 1 0-10.127 0 5.063 5.063 0 0 0 10.127 0z"
></path>
</svg>
</button>
</span>
</div>
<div
class=
"search-category"
>
<div
class=
"navbar"
>
<div
class=
"main-navbar"
>
<div
class=
"main-navbar-links"
>
<template
v-for=
"(item, index) in category"
>
<div
:class=
"mainNavLinkClass(index)"
:key=
"item.text"
>
<a
href=
"javascript:;"
@
click=
"categoryIndex = index"
>
{{
item
.
text
}}
</a>
</div>
</
template
>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"search-result"
></div>
</div>
</template>
<
script
>
import
NavbarLogo
from
'
../NavbarLogo.vue
'
;
import
{
search
as
searchClient
}
from
'
./searchClient
'
;
import
{
forbidScroll
}
from
'
../../util
'
;
const
resolveRoutePathFromUrl
=
(
url
,
base
=
'
/
'
)
=>
url
// remove url origin
.
replace
(
/^
(
https
?
:
)?\/\/[^/]
*/
,
''
)
// remove site base
.
replace
(
new
RegExp
(
`^
${
base
}
`
),
'
/
'
);
export
default
{
name
:
'
DcloudSearchPage
'
,
props
:
[
'
options
'
],
components
:
{
NavbarLogo
},
data
()
{
return
{
placeholder
:
'
搜索内容
'
,
snippetLength
:
10
,
searchValue
:
''
,
category
:
Object
.
freeze
([
{
text
:
'
uni-app
'
,
},
{
text
:
'
uniCloud
'
,
},
{
text
:
'
问答社区
'
,
},
{
text
:
'
插件市场
'
,
},
]),
categoryIndex
:
0
,
};
},
mounted
()
{
this
.
$nextTick
(
forbidScroll
);
const
isMobileMediaQuery
=
window
.
matchMedia
(
'
(max-width: 750px)
'
);
if
(
isMobileMediaQuery
.
matches
)
{
this
.
snippetLength
=
5
;
}
},
methods
:
{
search
()
{
this
.
searchByAlgolia
(
this
.
searchValue
);
},
searchByAlgolia
(
query
=
''
,
page
=
0
)
{
const
{
searchParameters
=
{}
}
=
this
.
options
;
return
searchClient
(
Object
.
assign
({},
this
.
options
,
{
query
,
page
,
snippetLength
:
this
.
snippetLength
,
searchParameters
:
{
...
searchParameters
,
facetFilters
:
[
`lang:
${
this
.
$lang
}
`
].
concat
(
searchParameters
.
facetFilters
||
[]),
},
transformItems
:
items
=>
items
.
map
(
item
=>
{
// the `item.url` is full url with protocol and hostname
// so we have to transform it to vue-router path
return
{
...
item
,
url
:
resolveRoutePathFromUrl
(
item
.
url
,
this
.
$site
.
base
),
};
}),
})
);
},
mainNavLinkClass
(
index
)
{
return
[
'
main-navbar-item
'
,
this
.
categoryIndex
===
index
?
'
active
'
:
''
];
},
},
};
</
script
>
<
style
lang=
"stylus"
>
$svg-color = #b1b2b3;
$svg-hover-color = #9b9b9b;
#search-container{
position fixed
width 100vw
height 100vh
left 0
top 0
z-index 200
background-color #fff
.sub-navbar {
width: 80%;
max-width: 960px;
min-width: 720px;
margin: 0 auto;
.search-wrap {
width: 100%;
display: inline-block;
vertical-align: middle;
position: relative;
}
.input-wrap {
margin-top: 24px;
position: relative;
display: flex;
align-items: center;
.search-input-btn {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0;
font-size: 0;
background-color: #fff;
button {
width: 40px;
font-family: inherit;
font-size: 100%;
margin: 0;
outline: 0;
background-color: transparent;
padding: 0;
border-width: 0;
vertical-align: middle;
cursor: pointer;
svg {
fill: $svg-color;
&:hover {
fill: $svg-hover-color;
}
}
}
}
.search-input {
width: 100%;
height: 56px;
font-size: 16px;
border: none;
box-sizing: border-box;
outline: none;
padding: 1px 10px;
border-radius: 4px;
}
.search-input-btn {
height: 56px;
}
}
.search-category {
.main-navbar-links {
width: 100%;
padding: 0;
.main-navbar-item {
padding: 0 6%;
}
}
}
}
}
</
style
>
docs/.vuepress/theme/components/DcloudSearchPage/searchClient.js
0 → 100644
浏览文件 @
36027151
import
algoliasearch
from
'
algoliasearch/dist/algoliasearch-lite.esm.browser
'
;
import
{
removeHighlightTags
,
groupBy
}
from
'
../../util
'
let
searchClient
function
createSearchClient
(
appId
,
apiKey
)
{
if
(
searchClient
)
return
searchClient
searchClient
=
algoliasearch
(
appId
,
apiKey
);
searchClient
.
addAlgoliaAgent
(
'
dcloudsearch
'
,
'
1.0.0
'
);
return
searchClient
}
export
function
search
({
query
,
indexName
,
appId
,
apiKey
,
searchParameters
=
{},
snippetLength
=
0
,
transformItems
=
()
=>
{
},
...
args
})
{
return
createSearchClient
(
appId
,
apiKey
)
.
search
([
{
query
,
indexName
,
params
:
{
attributesToRetrieve
:
[
'
hierarchy.lvl0
'
,
'
hierarchy.lvl1
'
,
'
hierarchy.lvl2
'
,
'
hierarchy.lvl3
'
,
'
hierarchy.lvl4
'
,
'
hierarchy.lvl5
'
,
'
hierarchy.lvl6
'
,
'
content
'
,
'
type
'
,
'
url
'
,
],
attributesToSnippet
:
[
`hierarchy.lvl1:
${
snippetLength
}
`
,
`hierarchy.lvl2:
${
snippetLength
}
`
,
`hierarchy.lvl3:
${
snippetLength
}
`
,
`hierarchy.lvl4:
${
snippetLength
}
`
,
`hierarchy.lvl5:
${
snippetLength
}
`
,
`hierarchy.lvl6:
${
snippetLength
}
`
,
`content:
${
snippetLength
}
`
,
],
snippetEllipsisText
:
'
…
'
,
highlightPreTag
:
'
<mark>
'
,
highlightPostTag
:
'
</mark>
'
,
hitsPerPage
:
20
,
...
args
,
...
searchParameters
,
},
},
])
.
catch
((
error
)
=>
{
throw
error
;
})
.
then
(({
results
})
=>
{
const
{
hits
,
nbHits
}
=
results
[
0
];
const
sources
=
groupBy
(
hits
,
(
hit
)
=>
removeHighlightTags
(
hit
));
return
Object
.
values
(
sources
).
map
(
(
items
,
index
)
=>
{
return
{
sourceId
:
`hits
${
index
}
`
,
onSelect
({
item
,
event
})
{
// saveRecentSearch(item);
// if (!event.shiftKey && !event.ctrlKey && !event.metaKey) {
// onClose();
// }
},
getItemUrl
({
item
})
{
return
item
.
url
;
},
getItems
()
{
return
Object
.
values
(
groupBy
(
items
,
(
item
)
=>
item
.
hierarchy
.
lvl1
)
)
.
map
(
transformItems
)
.
map
((
groupedHits
)
=>
groupedHits
.
map
((
item
)
=>
{
return
{
...
item
,
__docsearch_parent
:
item
.
type
!==
'
lvl1
'
&&
groupedHits
.
find
(
(
siblingItem
)
=>
siblingItem
.
type
===
'
lvl1
'
&&
siblingItem
.
hierarchy
.
lvl1
===
item
.
hierarchy
.
lvl1
),
};
})
).
flat
();
},
};
}
);
});
}
\ No newline at end of file
docs/.vuepress/theme/components/Navbar.vue
浏览文件 @
36027151
...
...
@@ -3,29 +3,7 @@
<div
class=
"main-navbar"
>
<!--
<SidebarButton
@
toggle-sidebar=
"$emit('toggle-sidebar')"
/>
-->
<a
href=
"https://www.dcloud.io"
class=
"home-link"
>
<img
v-if=
"$site.themeConfig.logo"
class=
"logo"
:src=
"$withBase($site.themeConfig.logo)"
:alt=
"$siteTitle"
>
<img
v-if=
"$site.themeConfig.titleLogo"
class=
"title-logo can-hide"
:src=
"$withBase($site.themeConfig.titleLogo)"
:alt=
"$siteTitle"
>
<span
v-else-if=
"$siteTitle"
ref=
"siteName"
class=
"site-name"
:class=
"
{ 'can-hide': $site.themeConfig.logo }"
>
{{
$siteTitle
}}
</span>
</a>
<NavbarLogo
/>
<div
class=
"main-navbar-links can-hide"
>
<template
v-for=
"(item, index) in customNavBar"
>
...
...
@@ -82,6 +60,7 @@ import SearchBox from './SearchBox'
import
SidebarButton
from
'
@theme/components/SidebarButton.vue
'
import
NavLinks
from
'
@theme/components/NavLinks.vue
'
import
MainNavbarLink
from
'
./MainNavbarLink.vue
'
;
import
NavbarLogo
from
'
./NavbarLogo.vue
'
;
import
navInject
from
'
../mixin/navInject
'
;
import
{
forbidScroll
,
os
}
from
'
../util
'
;
...
...
@@ -95,7 +74,8 @@ export default {
NavLinks
,
MainNavbarLink
,
SearchBox
,
AlgoliaSearchBox
AlgoliaSearchBox
,
NavbarLogo
},
data
()
{
...
...
docs/.vuepress/theme/components/NavbarLogo.vue
0 → 100644
浏览文件 @
36027151
<
template
>
<a
href=
"https://www.dcloud.io"
class=
"home-link"
>
<img
v-if=
"$site.themeConfig.logo"
class=
"logo"
:src=
"$withBase($site.themeConfig.logo)"
:alt=
"$siteTitle"
/>
<img
v-if=
"$site.themeConfig.titleLogo"
class=
"title-logo can-hide"
:src=
"$withBase($site.themeConfig.titleLogo)"
:alt=
"$siteTitle"
/>
<span
v-else-if=
"$siteTitle"
ref=
"siteName"
class=
"site-name"
:class=
"
{ 'can-hide': $site.themeConfig.logo }"
>
{{
$siteTitle
}}
</span>
</a>
</
template
>
docs/.vuepress/theme/layouts/Layout.vue
浏览文件 @
36027151
...
...
@@ -42,6 +42,8 @@
<Footer
/>
</
template
>
</Page>
<DcloudSearchPage
:options=
"algolia"
/>
</div>
</template>
...
...
@@ -52,6 +54,7 @@ import Page from '@theme/components/Page.vue'
import
Sidebar
from
'
@theme/components/Sidebar.vue
'
import
Footer
from
'
@theme/components/Footer.vue
'
;
import
SiderBarBottom
from
'
../components/SiderBarBottom.vue
'
;
import
DcloudSearchPage
from
'
../components/DcloudSearchPage
'
;
import
{
resolveSidebarItems
,
forbidScroll
,
BaiduStat
}
from
'
../util
'
import
navProvider
from
'
../mixin/navProvider
'
;
...
...
@@ -64,7 +67,8 @@ export default {
Sidebar
,
Navbar
,
Footer
,
SiderBarBottom
SiderBarBottom
,
DcloudSearchPage
},
data
()
{
return
{
...
...
@@ -114,6 +118,9 @@ export default {
},
userPageClass
]
},
algolia
()
{
return
this
.
$themeLocaleConfig
.
algolia
||
this
.
$site
.
themeConfig
.
algolia
||
{}
}
},
mounted
()
{
...
...
docs/.vuepress/theme/util/index.js
浏览文件 @
36027151
import
Vue
from
'
vue
'
;
export
*
from
'
./searchUtils
'
;
export
const
isServer
=
Vue
.
prototype
.
$isServer
export
const
hashRE
=
/#.*$/
export
const
extRE
=
/
\.(
md|html
)
$/
...
...
docs/.vuepress/theme/util/searchUtils.js
0 → 100644
浏览文件 @
36027151
export
function
groupBy
(
values
,
predicate
)
{
return
values
.
reduce
((
acc
,
item
)
=>
{
const
key
=
predicate
(
item
);
if
(
!
acc
.
hasOwnProperty
(
key
))
{
acc
[
key
]
=
[];
}
// We limit each section to show 5 hits maximum.
// This acts as a frontend alternative to `distinct`.
if
(
acc
[
key
].
length
<
5
)
{
acc
[
key
].
push
(
item
);
}
return
acc
;
},
{});
}
const
regexHighlightTags
=
/
(
<mark>|<
\/
mark>
)
/g
;
const
regexHasHighlightTags
=
RegExp
(
regexHighlightTags
.
source
);
export
function
removeHighlightTags
(
hit
)
{
const
internalDocSearchHit
=
hit
if
(
!
internalDocSearchHit
.
__docsearch_parent
&&
!
hit
.
_highlightResult
)
{
return
hit
.
hierarchy
.
lvl0
;
}
const
{
value
}
=
(
internalDocSearchHit
.
__docsearch_parent
?
internalDocSearchHit
.
__docsearch_parent
?.
_highlightResult
?.
hierarchy
?.
lvl0
:
hit
.
_highlightResult
?.
hierarchy
?.
lvl0
)
||
{};
return
value
&&
regexHasHighlightTags
.
test
(
value
)
?
value
.
replace
(
regexHighlightTags
,
''
)
:
value
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录