ant-design-vue/site/components/layout.vue

283 lines
9.4 KiB
Vue
Raw Normal View History

2018-04-09 22:49:58 +08:00
<script>
2018-07-13 21:55:29 +08:00
import AllDemo from '../demo'
2018-04-09 22:49:58 +08:00
import Header from './header'
2018-08-10 14:52:26 +08:00
import Footer from './footer'
2018-09-06 20:11:10 +08:00
import Sponsors from './sponsors'
2018-04-09 22:49:58 +08:00
import zhCN from 'antd/locale-provider/zh_CN'
import enUS from 'antd/locale-provider/default'
2018-07-14 17:10:50 +08:00
import sortBy from 'lodash/sortBy'
2018-04-09 22:49:58 +08:00
import { isZhCN } from '../util'
import { Provider, create } from '../../components/_util/store'
2018-07-14 17:59:25 +08:00
import NProgress from 'nprogress'
2018-04-09 22:49:58 +08:00
2018-06-04 14:58:02 +08:00
const docsList = [
{ key: 'introduce', enTitle: 'Ant Design of Vue', title: 'Ant Design of Vue' },
{ key: 'getting-started', enTitle: 'Getting Started', title: '快速上手' },
{ key: 'use-with-vue-cli', enTitle: 'Use in vue-cli', title: '在 vue-cli 中使用' },
{ key: 'customize-theme', enTitle: 'Customize Theme', title: '定制主题' },
{ key: 'changelog', enTitle: 'Change Log', title: '更新日志' },
{ key: 'i18n', enTitle: 'Internationalization', title: '国际化' },
]
2018-04-09 22:49:58 +08:00
export default {
props: {
name: String,
2018-07-13 21:55:29 +08:00
showDemo: Boolean,
showApi: Boolean,
2018-04-09 22:49:58 +08:00
},
data () {
this.store = create({
currentSubMenu: [],
})
this.subscribe()
return {
2018-08-05 22:25:51 +08:00
showSideBars: true,
2018-04-09 22:49:58 +08:00
currentSubMenu: [],
2018-08-05 22:25:51 +08:00
sidebarHeight: document.documentElement.offsetHeight,
2018-04-09 22:49:58 +08:00
}
},
2018-07-13 21:55:29 +08:00
provide () {
return {
demoContext: this,
}
},
2018-04-09 22:49:58 +08:00
beforeDestroy () {
if (this.unsubscribe) {
this.unsubscribe()
}
2018-07-14 17:59:25 +08:00
clearTimeout(this.timer)
2018-08-05 22:25:51 +08:00
if (this.resizeEvent) {
this.resizeEvent.remove()
}
if (this.debouncedResize && this.debouncedResize.cancel) {
this.debouncedResize.cancel()
}
2018-04-09 22:49:58 +08:00
},
2018-04-10 21:44:45 +08:00
mounted () {
2018-08-05 22:25:51 +08:00
this.$nextTick(() => {
this.addSubMenu()
const nprogressHiddenStyle = document.getElementById('nprogress-style')
if (nprogressHiddenStyle) {
this.timer = setTimeout(() => {
nprogressHiddenStyle.parentNode.removeChild(nprogressHiddenStyle)
}, 0)
}
})
2018-04-10 21:44:45 +08:00
},
2018-04-09 22:49:58 +08:00
watch: {
2018-04-10 21:44:45 +08:00
'$route.path': function () {
2018-04-09 22:49:58 +08:00
this.store.setState({ currentSubMenu: [] })
2018-04-10 21:44:45 +08:00
this.addSubMenu()
2018-04-09 22:49:58 +08:00
},
},
methods: {
2018-04-10 21:44:45 +08:00
addSubMenu () {
if (this.$route.path.indexOf('/docs/vue/') !== -1) {
this.$nextTick(() => {
const menus = []
2018-07-28 13:43:23 +08:00
const doms = [...this.$refs.doc.querySelectorAll(['h2', 'h3'])]
doms.forEach(dom => {
2018-04-10 21:44:45 +08:00
const id = dom.id
if (id) {
const title = dom.textContent.split('#')[0].trim()
menus.push({ cnTitle: title, usTitle: title, id })
}
})
this.currentSubMenu = menus
})
}
},
2018-04-09 22:49:58 +08:00
subscribe () {
const { store } = this
this.unsubscribe = store.subscribe(() => {
this.currentSubMenu = this.store.getState().currentSubMenu
})
},
getSubMenu (isCN) {
const currentSubMenu = this.currentSubMenu
const lis = []
currentSubMenu.forEach(({ cnTitle, usTitle, id }) => {
const title = isCN ? cnTitle : usTitle
lis.push(<a-anchor-link key={id} href={`#${id}`} title={title} />)
2018-04-09 22:49:58 +08:00
})
2018-04-10 21:44:45 +08:00
const showApi = this.$route.path.indexOf('/components/') !== -1
2018-04-09 22:49:58 +08:00
return (
<a-anchor offsetTop={100} class='demo-anchor'>
2018-07-14 17:10:50 +08:00
{lis}
{showApi ? <a-anchor-link key='API' title='API' href='#API' /> : ''}
2018-07-14 17:10:50 +08:00
</a-anchor>
2018-04-09 22:49:58 +08:00
)
},
2018-08-10 14:52:26 +08:00
getDocsMenu (isCN, pagesKey) {
2018-04-09 22:49:58 +08:00
const docsMenu = []
2018-08-10 14:52:26 +08:00
docsList.forEach(({ key, enTitle, title }, index) => {
2018-04-09 22:49:58 +08:00
const k = isCN ? `${key}-cn` : key
2018-08-10 14:52:26 +08:00
pagesKey.push({ name: k,
url: `/ant-design-vue/docs/vue/${k}/`,
title: isCN ? title : enTitle,
})
2018-04-09 22:49:58 +08:00
docsMenu.push(<a-menu-item key={k}>
<router-link to={`/ant-design-vue/docs/vue/${k}/`}>{isCN ? title : enTitle }</router-link>
2018-04-09 22:49:58 +08:00
</a-menu-item>)
})
return docsMenu
},
2018-06-04 14:58:02 +08:00
resetDocumentTitle (component, name, isCN) {
2018-08-11 10:54:00 +08:00
let titleStr = 'Ant Design Vue'
2018-06-04 14:58:02 +08:00
if (component) {
const { subtitle, title } = component
const componentName = isCN ? subtitle + ' ' + title : title
titleStr = componentName + ' - ' + titleStr
} else {
const currentKey = docsList.filter((item) => {
return item.key === name
})
if (currentKey.length) {
titleStr = (isCN ? currentKey[0]['title'] : currentKey[0]['enTitle']) + ' - ' + titleStr
}
}
document.title = titleStr
},
2018-07-14 17:59:25 +08:00
mountedCallback () {
NProgress.done()
2018-08-05 22:25:51 +08:00
document.documentElement.scrollTop = 0
2018-07-14 17:59:25 +08:00
},
2018-04-09 22:49:58 +08:00
},
2018-07-13 21:55:29 +08:00
2018-04-09 22:49:58 +08:00
render () {
const name = this.name
const isCN = isZhCN(name)
const titleMap = {}
const menuConfig = {
General: [],
Layout: [],
Navigation: [],
'Data Entry': [],
'Data Display': [],
Feedback: [],
Other: [],
}
2018-08-10 14:52:26 +08:00
const pagesKey = []
let prevPage = null
let nextPage = null
2018-04-11 13:32:18 +08:00
const searchData = []
2018-04-09 22:49:58 +08:00
for (const [title, d] of Object.entries(AllDemo)) {
const type = d.type || 'Other'
const key = `${title.replace(/(\B[A-Z])/g, '-$1').toLowerCase()}`
titleMap[key] = title
2018-07-13 21:55:29 +08:00
AllDemo[title].key = key
2018-04-09 22:49:58 +08:00
menuConfig[type] = menuConfig[type] || []
menuConfig[type].push(d)
}
2018-08-10 14:52:26 +08:00
const docsMenu = this.getDocsMenu(isCN, pagesKey)
2018-06-04 14:58:02 +08:00
const reName = name.replace(/-cn\/?$/, '')
2018-04-09 22:49:58 +08:00
const MenuGroup = []
for (const [type, menus] of Object.entries(menuConfig)) {
const MenuItems = []
2018-07-14 17:10:50 +08:00
sortBy(menus, ['title']).forEach(({ title, subtitle }) => {
2018-04-09 22:49:58 +08:00
const linkValue = isCN
? [<span>{title}</span>, <span class='chinese'>{subtitle}</span>]
: [<span>{title}</span>]
let key = `${title.replace(/(\B[A-Z])/g, '-$1').toLowerCase()}`
if (isCN) {
key = `${key}-cn`
}
2018-08-10 14:52:26 +08:00
pagesKey.push({
name: key,
url: `/ant-design-vue/components/${key}/`,
title: isCN ? `${title} ${subtitle}` : title,
})
2018-04-11 13:32:18 +08:00
searchData.push({
title,
subtitle,
url: `/ant-design-vue/components/${key}/`,
2018-04-11 13:32:18 +08:00
})
2018-04-09 22:49:58 +08:00
MenuItems.push(<a-menu-item key={key}>
<router-link to={`/ant-design-vue/components/${key}/`}>{linkValue}</router-link>
2018-04-09 22:49:58 +08:00
</a-menu-item>)
})
MenuGroup.push(<a-menu-item-group title={type}>{MenuItems}</a-menu-item-group>)
}
2018-08-10 14:52:26 +08:00
pagesKey.forEach((item, index) => {
if (item.name === name) {
prevPage = pagesKey[index - 1]
nextPage = pagesKey[index + 1]
}
})
2018-04-09 22:49:58 +08:00
let locale = zhCN
if (!isCN) {
locale = enUS
}
2018-07-14 17:10:50 +08:00
const config = AllDemo[titleMap[reName]]
this.resetDocumentTitle(config, reName, isCN)
2018-08-10 14:52:26 +08:00
const { showSideBars } = this
2018-04-09 22:49:58 +08:00
return (
<div class='page-wrapper'>
2018-04-14 21:49:27 +08:00
<Header searchData={searchData} name={name}/>
2018-04-09 22:49:58 +08:00
<a-locale-provider locale={locale}>
<div class='main-wrapper'>
<a-row>
2018-08-10 14:52:26 +08:00
<a-col v-show={showSideBars} ref='sidebar' class='site-sidebar' xxl={4} xl={5} lg={5} md={6} sm={8} xs={12}>
2018-08-05 22:25:51 +08:00
<div class='drawer-mask' onClick={() => { this.showSideBars = false }}></div>
2018-09-06 20:11:10 +08:00
<Sponsors title={isCN ? '赞助商' : 'Sponsors'}/>
2018-04-09 22:49:58 +08:00
<a-menu
class='aside-container menu-site'
selectedKeys={[name]}
defaultOpenKeys={['Components']}
inlineIndent={40}
mode='inline'>
2018-08-10 14:52:26 +08:00
{docsMenu}
2018-04-14 21:49:27 +08:00
<a-sub-menu title={`Components(${searchData.length})`} key='Components'>
2018-04-09 22:49:58 +08:00
{MenuGroup}
</a-sub-menu>
</a-menu>
2018-08-05 22:25:51 +08:00
<div class='close-drawer' onClick={() => { this.showSideBars = false }}>
<a-icon type='close'/>
</div>
2018-04-09 22:49:58 +08:00
</a-col>
2018-08-05 22:25:51 +08:00
<div v-show={!showSideBars} class='open-drawer' onClick={() => { this.showSideBars = true }}>
<a-icon type='bars'/>
</div>
2018-08-11 10:54:00 +08:00
<a-col class='main-container' xxl={20} xl={19} lg={19} md={18} sm={24} xs={24}>
<div class='content'>
2018-07-14 17:10:50 +08:00
<div class='toc-affix' style='width: 120px;'>
2018-04-10 21:44:45 +08:00
{this.getSubMenu(isCN)}
2018-04-09 22:49:58 +08:00
</div>
2018-07-13 21:55:29 +08:00
{this.showDemo ? <Provider store={this.store} key={isCN ? 'cn' : 'en'}>
2018-07-14 17:59:25 +08:00
<router-view
class={`demo-cols-${config.cols || 2}`}
{...{ directives: [
{
name: 'mountedCallback',
value: this.mountedCallback,
},
] }}
></router-view>
2018-04-09 22:49:58 +08:00
</Provider> : ''}
2018-07-13 21:55:29 +08:00
{this.showApi ? <div class='markdown api-container' ref='doc'>
2018-07-14 17:59:25 +08:00
<router-view
{...{ directives: [
{
name: 'mountedCallback',
value: this.mountedCallback,
},
] }}
></router-view>
2018-07-13 21:55:29 +08:00
</div> : ''}
2018-04-09 22:49:58 +08:00
</div>
2018-08-10 14:52:26 +08:00
<section class='prev-next-nav'>
{prevPage ? <router-link class='prev-page' to={`${prevPage.url}`}>{prevPage.title}</router-link> : ''}
{nextPage ? <router-link class='next-page' to={`${nextPage.url}`}>{nextPage.title}</router-link> : ''}
</section>
2018-04-09 22:49:58 +08:00
</a-col>
</a-row>
</div>
</a-locale-provider>
2018-08-10 14:52:26 +08:00
<Footer ref='footer' isCN={isCN}/>
2018-07-13 21:55:29 +08:00
{ name.indexOf('back-top') === -1 ? <a-back-top /> : null }
2018-04-09 22:49:58 +08:00
</div>
)
},
}
</script>