feat: upgrade sidebar, remove header, upgrade search
This commit is contained in:
@@ -1,89 +0,0 @@
|
||||
<template>
|
||||
<header class="one-header">
|
||||
<h1>Baidu DLS</h1>
|
||||
<a
|
||||
href="http://dls.baidu.com/"
|
||||
target="_blank"
|
||||
>返回 DLS</a>
|
||||
<veui-dropdown
|
||||
label="Vue"
|
||||
:options="options"
|
||||
@click="redirect"
|
||||
/>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Dropdown } from 'veui'
|
||||
|
||||
export default {
|
||||
name: 'one-header',
|
||||
components: {
|
||||
'veui-dropdown': Dropdown
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
options: [
|
||||
{
|
||||
label: 'Vue',
|
||||
value: '/'
|
||||
},
|
||||
{
|
||||
label: 'React',
|
||||
value: 'http://one-ui.baidu-int.com/'
|
||||
},
|
||||
{
|
||||
label: 'Angular',
|
||||
value: 'http://cp01-wangfengjiao01.epc.baidu.com:8404/'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
redirect (url) {
|
||||
location.href = url
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.one-header
|
||||
position fixed
|
||||
top 0
|
||||
left 0
|
||||
right 0
|
||||
z-index 20
|
||||
display flex
|
||||
align-items center
|
||||
height 60px
|
||||
background-color #070628
|
||||
color #ffffff
|
||||
padding 0 51px 0 17px
|
||||
|
||||
h1
|
||||
display inline-block
|
||||
font-size 18px
|
||||
|
||||
a
|
||||
margin-left auto
|
||||
color #ffffff
|
||||
font-size 16px
|
||||
|
||||
&:hover
|
||||
color #ffffff
|
||||
|
||||
.veui-dropdown
|
||||
margin-left 40px
|
||||
|
||||
& >>> .veui-dropdown-button
|
||||
color #ffffff
|
||||
background-color transparent
|
||||
border-radius 6px
|
||||
height 28px
|
||||
display inline-flex
|
||||
align-items center
|
||||
|
||||
.veui-dropdown-label
|
||||
line-height 1
|
||||
</style>
|
@@ -1,90 +1,53 @@
|
||||
<template>
|
||||
<aside class="one-nav">
|
||||
<nav class="secondary">
|
||||
<h2><span>VEUI<small>beta</small></span></h2>
|
||||
<section class="desc">
|
||||
<a href="https://github.com/ecomfe/veui">
|
||||
<img
|
||||
alt="VEUI on GitHub"
|
||||
src="https://badgen.net/badge/-/GitHub?icon=github&label"
|
||||
width="69.2"
|
||||
height="20"
|
||||
>
|
||||
</a>
|
||||
<nuxt-link
|
||||
:class="{
|
||||
'locale-swith': true,
|
||||
disabled: altLocale.disabled
|
||||
}"
|
||||
:to="altLocale.disabled ? '' : altLocale.to"
|
||||
>
|
||||
{{ altLocale.label }}
|
||||
</nuxt-link>
|
||||
</section>
|
||||
<section class="filter">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search…"
|
||||
class="search"
|
||||
>
|
||||
</section>
|
||||
<menu class="menu">
|
||||
<template v-for="(item, i) in nav">
|
||||
<li
|
||||
:key="`menu-${i}`"
|
||||
class="menu-item"
|
||||
>
|
||||
<nuxt-link
|
||||
v-if="item.link !== false"
|
||||
class="menu-link"
|
||||
:exact="item.exact"
|
||||
:to="getLocalePath(`/${item.slug}`)"
|
||||
<veui-menu
|
||||
class="one-menu"
|
||||
:items="menuItems"
|
||||
:expanded.sync="expanded"
|
||||
>
|
||||
<template #before>
|
||||
<h2>VEUI</h2>
|
||||
<section class="desc">
|
||||
<a href="https://github.com/ecomfe/veui">
|
||||
<img
|
||||
alt="VEUI on GitHub"
|
||||
src="https://badgen.net/badge/-/GitHub?icon=github&label"
|
||||
width="69.2"
|
||||
height="20"
|
||||
>
|
||||
{{ item.title }}
|
||||
</nuxt-link>
|
||||
<span
|
||||
v-else
|
||||
class="menu-link"
|
||||
>{{ item.title }}</span>
|
||||
<menu
|
||||
v-if="item.children && item.children.length"
|
||||
class="menu"
|
||||
>
|
||||
<template
|
||||
v-for="(subItem, j) in item.children"
|
||||
>
|
||||
<li
|
||||
v-if="!subItem.hidden"
|
||||
:key="`sub-${j}`"
|
||||
class="menu-item"
|
||||
>
|
||||
<nuxt-link
|
||||
:class="{
|
||||
'menu-link': true,
|
||||
'menu-link-disabled': subItem.disabled,
|
||||
'menu-link-sub': subItem.sub,
|
||||
'menu-link-active': isActive(`/${item.slug}/${subItem.slug}`)
|
||||
}"
|
||||
:exact="subItem.exact"
|
||||
:to="subItem.disabled ? '/' : getLocalePath(`/${item.slug}/${subItem.slug}`)"
|
||||
v-html="getTitleHTML(subItem.title)"
|
||||
/>
|
||||
</li>
|
||||
</template>
|
||||
</menu>
|
||||
</li>
|
||||
</template>
|
||||
</menu>
|
||||
</nav>
|
||||
</a>
|
||||
<nuxt-link
|
||||
:class="{
|
||||
'locale-swith': true,
|
||||
disabled: altLocale.disabled,
|
||||
}"
|
||||
:to="altLocale.disabled ? '' : altLocale.to"
|
||||
>
|
||||
{{ altLocale.label }}
|
||||
</nuxt-link>
|
||||
</section>
|
||||
<section class="filter">
|
||||
<one-search/>
|
||||
</section>
|
||||
</template>
|
||||
<template #item-label="{ label, sub }">
|
||||
{{ label }}<small>{{ sub }}</small>
|
||||
</template>
|
||||
</veui-menu>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { escape } from 'lodash'
|
||||
import i18n from '../common/i18n'
|
||||
import OneSearch from './OneSearch'
|
||||
import { Menu } from 'veui'
|
||||
|
||||
export default {
|
||||
name: 'one-menu',
|
||||
components: {
|
||||
'one-search': OneSearch,
|
||||
'veui-menu': Menu
|
||||
},
|
||||
mixins: [i18n],
|
||||
props: {
|
||||
nav: {
|
||||
@@ -94,6 +57,11 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
expanded: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
altLocale () {
|
||||
let { canonicalPath, locale, getLocalePath, isPathDisabled } = this
|
||||
@@ -105,52 +73,37 @@ export default {
|
||||
disabled,
|
||||
label
|
||||
}
|
||||
},
|
||||
menuItems () {
|
||||
return this.nav.map(item => this.normalizeItem(item))
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: 'scrollActiveIntoView'
|
||||
},
|
||||
mounted () {
|
||||
this.scrollActiveIntoView()
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearTimeout(this.timer)
|
||||
created () {
|
||||
this.expanded = this.menuItems.map(({ name }) => name)
|
||||
},
|
||||
methods: {
|
||||
getTitleHTML (title) {
|
||||
getTitleDetail (title) {
|
||||
let [main, sub] = title.split(' - ')
|
||||
return escape(main) + (sub ? `<small>${escape(sub)}</small>` : '')
|
||||
return [main, sub]
|
||||
},
|
||||
isActive (path) {
|
||||
let { route = {} } = this.$router.resolve(path) || {}
|
||||
return route.name === this.$route.name
|
||||
},
|
||||
scrollActiveIntoView () {
|
||||
this.timer = setTimeout(() => {
|
||||
if (!this.$el) {
|
||||
return
|
||||
}
|
||||
let active =
|
||||
this.$el.querySelector('.nuxt-link-exact-active') ||
|
||||
this.$el.querySelector('.menu-link-active')
|
||||
if (!active) {
|
||||
return
|
||||
}
|
||||
normalizeItem ({ title, children, slug, link, disabled }, base = '') {
|
||||
const fullSlug = `${base}/${slug}`
|
||||
const localePath = this.getLocalePath(fullSlug)
|
||||
const to = (link !== false && fullSlug) ? localePath : null
|
||||
const [main, sub] = this.getTitleDetail(title)
|
||||
|
||||
let menu = active.offsetParent
|
||||
if (!menu) {
|
||||
return
|
||||
}
|
||||
if (
|
||||
active.offsetTop < menu.scrollTop ||
|
||||
active.offsetTop + active.offsetHeight > menu.scrollTop
|
||||
) {
|
||||
active.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'nearest'
|
||||
})
|
||||
}
|
||||
})
|
||||
return {
|
||||
label: main,
|
||||
sub,
|
||||
to,
|
||||
name: fullSlug,
|
||||
disabled,
|
||||
children: children ? children.map(child => this.normalizeItem(child, fullSlug)) : []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,43 +112,33 @@ export default {
|
||||
<style lang="stylus" scoped>
|
||||
.one-nav
|
||||
position fixed
|
||||
top 60px
|
||||
top 0
|
||||
bottom 0
|
||||
left 0
|
||||
width 280px
|
||||
z-index 1
|
||||
padding-top 30px
|
||||
border-right 1px solid #e5e5e5
|
||||
|
||||
.primary
|
||||
margin-left -250px
|
||||
|
||||
.secondary
|
||||
.one-menu
|
||||
width 100%
|
||||
height 100%
|
||||
position relative
|
||||
display flex
|
||||
justify-content stretch
|
||||
flex-direction column
|
||||
float left
|
||||
width 240px
|
||||
|
||||
::v-deep .veui-menu-tree-wrapper
|
||||
display flex
|
||||
flex-direction column
|
||||
flex-grow 1
|
||||
height 100%
|
||||
overflow visible
|
||||
|
||||
.veui-menu-tree
|
||||
overflow auto
|
||||
|
||||
h2
|
||||
display flex
|
||||
align-items center
|
||||
margin 0 0 0 20px
|
||||
margin 30px 0 0 20px
|
||||
font-size 20px
|
||||
font-weight 500
|
||||
|
||||
span
|
||||
position relative
|
||||
|
||||
small
|
||||
position absolute
|
||||
font-size 16px
|
||||
font-weight 400
|
||||
transform scale(0.75) translateY(-3px)
|
||||
margin-left 3px
|
||||
opacity 0.7
|
||||
|
||||
a
|
||||
display block
|
||||
|
||||
@@ -208,6 +151,10 @@ export default {
|
||||
img
|
||||
display block
|
||||
|
||||
small
|
||||
margin-left 8px
|
||||
opacity 0.7
|
||||
|
||||
.locale-swith
|
||||
display block
|
||||
margin-left 12px
|
||||
@@ -224,8 +171,7 @@ export default {
|
||||
border-color #999
|
||||
|
||||
.filter
|
||||
margin-top 20px
|
||||
margin-left 20px
|
||||
margin 20px 0 20px 20px
|
||||
|
||||
.search
|
||||
display block
|
||||
@@ -242,66 +188,6 @@ export default {
|
||||
border-color #999
|
||||
box-shadow 0 0 0 2px rgba(0, 0, 0, 0.15)
|
||||
|
||||
& > .menu
|
||||
position relative
|
||||
width 100%
|
||||
flex 1 1 auto
|
||||
margin-top 25px
|
||||
padding-left 20px
|
||||
overflow auto
|
||||
|
||||
.menu
|
||||
.menu-item
|
||||
.menu-link
|
||||
float left
|
||||
clear left
|
||||
|
||||
.menu .menu
|
||||
margin 3.5px 0
|
||||
|
||||
.menu-item
|
||||
margin 3.5px 0
|
||||
font-size 16px
|
||||
|
||||
.menu-item
|
||||
font-size 13px
|
||||
|
||||
.menu-link
|
||||
color #333
|
||||
font-weight 400
|
||||
|
||||
& >>> small
|
||||
color #999
|
||||
font-size 13px
|
||||
margin-left 10px
|
||||
white-space nowrap
|
||||
|
||||
&::after
|
||||
display block
|
||||
|
||||
.menu-link
|
||||
float left
|
||||
clear left
|
||||
color #333
|
||||
font-weight 500
|
||||
padding 9px 0
|
||||
text-decoration none
|
||||
|
||||
&-disabled
|
||||
opacity 0.3
|
||||
pointer-events none
|
||||
|
||||
// &-sub
|
||||
// margin-left 10px
|
||||
&::after
|
||||
background-color #999
|
||||
|
||||
.nuxt-link-exact-active::after
|
||||
.menu-link-active::after
|
||||
width 100%
|
||||
left 0
|
||||
background-color #333
|
||||
|
||||
.toggle
|
||||
margin-right 15px
|
||||
font-size 13px
|
||||
|
107
components/OneSearch.vue
Normal file
107
components/OneSearch.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<div id="docsearch"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import i18n from '../common/i18n'
|
||||
|
||||
function isSpecialClick (event) {
|
||||
return (
|
||||
event.button === 1 ||
|
||||
event.altKey ||
|
||||
event.ctrlKey ||
|
||||
event.metaKey ||
|
||||
event.shiftKey
|
||||
)
|
||||
}
|
||||
export default {
|
||||
name: 'one-search',
|
||||
mixins: [i18n],
|
||||
watch: {
|
||||
locale (val) {
|
||||
this.update(val)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.initialize(this.locale)
|
||||
},
|
||||
methods: {
|
||||
getRelativePath (absoluteUrl) {
|
||||
const { pathname, hash } = new URL(absoluteUrl)
|
||||
return `${pathname}/${hash}`
|
||||
},
|
||||
initialize (locale) {
|
||||
Promise.all([
|
||||
import(/* webpackChunkName: "docsearch" */ '@docsearch/js'),
|
||||
import(/* webpackChunkName: "docsearch" */ '@docsearch/css')
|
||||
]).then(([docsearch]) => {
|
||||
docsearch = docsearch.default
|
||||
docsearch({
|
||||
apiKey: '21cdc123c620ec4bb81259c32e90c08f',
|
||||
indexName: 'veui',
|
||||
container: '#docsearch',
|
||||
searchParameters: {
|
||||
facetFilters: [`lang:${locale}`]
|
||||
},
|
||||
navigator: {
|
||||
navigate ({ suggestionUrl }) {
|
||||
const { pathname: hitPathname } = new URL(
|
||||
window.location.origin + suggestionUrl
|
||||
)
|
||||
if (this.$router.history.current.path === hitPathname) {
|
||||
window.location.assign(window.location.origin + suggestionUrl)
|
||||
} else {
|
||||
this.$router.push(suggestionUrl)
|
||||
}
|
||||
}
|
||||
},
|
||||
transformItems: items => {
|
||||
return items.map(item => {
|
||||
return {
|
||||
...item,
|
||||
url: this.getRelativePath(item.url)
|
||||
}
|
||||
})
|
||||
},
|
||||
hitComponent: ({ hit, children }) => {
|
||||
return {
|
||||
type: 'a',
|
||||
ref: undefined,
|
||||
constructor: undefined,
|
||||
key: undefined,
|
||||
props: {
|
||||
href: hit.url,
|
||||
onClick: event => {
|
||||
if (isSpecialClick(event)) {
|
||||
return
|
||||
}
|
||||
// We rely on the native link scrolling when user is
|
||||
// already on the right anchor because Vue Router doesn't
|
||||
// support duplicated history entries.
|
||||
if (this.$router.history.current.fullPath === hit.url) {
|
||||
return
|
||||
}
|
||||
const { pathname: hitPathname } = new URL(
|
||||
window.location.origin + hit.url
|
||||
)
|
||||
// If the hits goes to another page, we prevent the native link behavior
|
||||
// to leverage the Vue Router loading feature.
|
||||
if (this.$router.history.current.path !== hitPathname) {
|
||||
event.preventDefault()
|
||||
}
|
||||
this.$router.push(hit.url)
|
||||
},
|
||||
children
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
update (locale) {
|
||||
this.$el.innerHTML = '<div id="docsearch"></div>'
|
||||
this.initialize(locale)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user