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

356 lines
12 KiB
Vue
Raw Normal View History

2018-04-09 14:49:58 +00:00
<script>
2019-01-12 09:19:57 +00:00
import { enquireScreen } from 'enquire-js';
2019-01-12 03:33:27 +00:00
import AllDemo from '../demo';
import Header from './header';
import Footer from './footer';
2019-01-17 03:59:21 +00:00
import CarbonAds from './CarbonAds';
2019-03-18 09:09:41 +00:00
import Geektime from './geektime';
2019-08-04 13:14:08 +00:00
import GeektimeAds from './geektime_ads';
2019-01-12 03:33:27 +00:00
import Sponsors from './sponsors';
import zhCN from 'antd/locale-provider/zh_CN';
import enUS from 'antd/locale-provider/default';
import sortBy from 'lodash/sortBy';
import { isZhCN } from '../util';
import { Provider, create } from '../../components/_util/store';
import NProgress from 'nprogress';
2019-01-16 03:26:56 +00:00
import MobileMenu from '../../components/vc-drawer/src';
2018-04-09 14:49:58 +00:00
2018-06-04 06:58:02 +00: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-12-14 13:35:19 +00:00
{ key: 'faq', enTitle: 'FAQ', title: '常见问题' },
2019-01-12 09:19:57 +00:00
{ key: 'sponsor', enTitle: 'Sponsor', title: '支持我们' },
{ key: 'download', enTitle: 'Download Design Resources', title: '下载设计资源' },
2019-01-12 03:33:27 +00:00
];
2018-06-04 06:58:02 +00:00
2019-01-12 09:19:57 +00:00
let isMobile = false;
enquireScreen(b => {
isMobile = b;
});
2018-04-09 14:49:58 +00:00
export default {
props: {
name: String,
2018-07-13 13:55:29 +00:00
showDemo: Boolean,
showApi: Boolean,
2018-04-09 14:49:58 +00:00
},
2019-08-12 12:38:09 +00:00
data() {
2018-04-09 14:49:58 +00:00
this.store = create({
currentSubMenu: [],
2019-01-12 03:33:27 +00:00
});
this.subscribe();
2018-04-09 14:49:58 +00:00
return {
2018-08-05 14:25:51 +00:00
showSideBars: true,
2018-04-09 14:49:58 +00:00
currentSubMenu: [],
2018-08-05 14:25:51 +00:00
sidebarHeight: document.documentElement.offsetHeight,
2019-01-12 09:19:57 +00:00
isMobile,
2019-01-12 03:33:27 +00:00
};
2018-04-09 14:49:58 +00:00
},
2019-08-12 12:38:09 +00:00
provide() {
2018-07-13 13:55:29 +00:00
return {
demoContext: this,
2019-01-12 03:33:27 +00:00
};
2018-07-13 13:55:29 +00:00
},
2019-02-01 09:23:00 +00:00
watch: {
2019-08-12 12:38:09 +00:00
'$route.path': function() {
2019-02-01 09:23:00 +00:00
this.store.setState({ currentSubMenu: [] });
this.addSubMenu();
},
},
2019-08-12 12:38:09 +00:00
beforeDestroy() {
2018-04-09 14:49:58 +00:00
if (this.unsubscribe) {
2019-01-12 03:33:27 +00:00
this.unsubscribe();
2018-04-09 14:49:58 +00:00
}
2019-01-12 03:33:27 +00:00
clearTimeout(this.timer);
2018-08-05 14:25:51 +00:00
if (this.resizeEvent) {
2019-01-12 03:33:27 +00:00
this.resizeEvent.remove();
2018-08-05 14:25:51 +00:00
}
if (this.debouncedResize && this.debouncedResize.cancel) {
2019-01-12 03:33:27 +00:00
this.debouncedResize.cancel();
2018-08-05 14:25:51 +00:00
}
2018-04-09 14:49:58 +00:00
},
2019-08-12 12:38:09 +00:00
mounted() {
2018-08-05 14:25:51 +00:00
this.$nextTick(() => {
2019-01-12 03:33:27 +00:00
this.addSubMenu();
const nprogressHiddenStyle = document.getElementById('nprogress-style');
2018-08-05 14:25:51 +00:00
if (nprogressHiddenStyle) {
this.timer = setTimeout(() => {
2019-01-12 03:33:27 +00:00
nprogressHiddenStyle.parentNode.removeChild(nprogressHiddenStyle);
}, 0);
2018-08-05 14:25:51 +00:00
}
2019-01-12 09:19:57 +00:00
enquireScreen(b => {
this.isMobile = !!b;
});
2019-01-12 03:33:27 +00:00
});
2018-04-10 13:44:45 +00:00
},
2018-04-09 14:49:58 +00:00
methods: {
2019-08-12 12:38:09 +00:00
addSubMenu() {
2018-04-10 13:44:45 +00:00
if (this.$route.path.indexOf('/docs/vue/') !== -1) {
this.$nextTick(() => {
2019-01-12 03:33:27 +00:00
const menus = [];
const doms = [...this.$refs.doc.querySelectorAll(['h2', 'h3'])];
2018-07-28 05:43:23 +00:00
doms.forEach(dom => {
2019-01-12 03:33:27 +00:00
const id = dom.id;
2018-04-10 13:44:45 +00:00
if (id) {
2019-01-12 03:33:27 +00:00
const title = dom.textContent.split('#')[0].trim();
menus.push({ cnTitle: title, usTitle: title, id });
2018-04-10 13:44:45 +00:00
}
2019-01-12 03:33:27 +00:00
});
this.currentSubMenu = menus;
});
2018-04-10 13:44:45 +00:00
}
},
2019-08-12 12:38:09 +00:00
subscribe() {
2019-01-12 03:33:27 +00:00
const { store } = this;
2018-04-09 14:49:58 +00:00
this.unsubscribe = store.subscribe(() => {
2019-01-12 03:33:27 +00:00
this.currentSubMenu = this.store.getState().currentSubMenu;
});
2018-04-09 14:49:58 +00:00
},
2019-08-12 12:38:09 +00:00
getSubMenu(isCN) {
2019-01-12 03:33:27 +00:00
const currentSubMenu = this.currentSubMenu;
const lis = [];
2018-04-09 14:49:58 +00:00
currentSubMenu.forEach(({ cnTitle, usTitle, id }) => {
2019-01-12 03:33:27 +00:00
const title = isCN ? cnTitle : usTitle;
lis.push(<a-anchor-link key={id} href={`#${id}`} title={title} />);
});
const showApi = this.$route.path.indexOf('/components/') !== -1;
2018-04-09 14:49:58 +00:00
return (
2019-08-12 12:38:09 +00:00
<a-anchor offsetTop={100} class="demo-anchor">
2018-07-14 09:10:50 +00:00
{lis}
2019-08-12 12:38:09 +00:00
{showApi ? <a-anchor-link key="API" title="API" href="#API" /> : ''}
2018-07-14 09:10:50 +00:00
</a-anchor>
2019-01-12 03:33:27 +00:00
);
2018-04-09 14:49:58 +00:00
},
2019-08-12 12:38:09 +00:00
getDocsMenu(isCN, pagesKey) {
2019-01-12 03:33:27 +00:00
const docsMenu = [];
2018-08-10 06:52:26 +00:00
docsList.forEach(({ key, enTitle, title }, index) => {
2019-01-12 03:33:27 +00:00
const k = isCN ? `${key}-cn` : key;
2019-08-12 12:38:09 +00:00
pagesKey.push({ name: k, url: `/docs/vue/${k}/`, title: isCN ? title : enTitle });
docsMenu.push(
<a-menu-item key={k}>
<router-link to={`/docs/vue/${k}/`}>{isCN ? title : enTitle}</router-link>
</a-menu-item>,
);
2019-01-12 03:33:27 +00:00
});
return docsMenu;
2018-04-09 14:49:58 +00:00
},
2019-08-12 12:38:09 +00:00
resetDocumentTitle(component, name, isCN) {
2019-01-12 03:33:27 +00:00
let titleStr = 'Ant Design Vue';
2018-06-04 06:58:02 +00:00
if (component) {
2019-01-12 03:33:27 +00:00
const { subtitle, title } = component;
const componentName = isCN ? subtitle + ' ' + title : title;
titleStr = componentName + ' - ' + titleStr;
2018-06-04 06:58:02 +00:00
} else {
2019-08-12 12:38:09 +00:00
const currentKey = docsList.filter(item => {
2019-01-12 03:33:27 +00:00
return item.key === name;
});
2018-06-04 06:58:02 +00:00
if (currentKey.length) {
2019-01-12 03:33:27 +00:00
titleStr = (isCN ? currentKey[0]['title'] : currentKey[0]['enTitle']) + ' - ' + titleStr;
2018-06-04 06:58:02 +00:00
}
}
2019-01-12 03:33:27 +00:00
document.title = titleStr;
2018-06-04 06:58:02 +00:00
},
2019-08-12 12:38:09 +00:00
mountedCallback() {
2019-01-12 03:33:27 +00:00
NProgress.done();
document.documentElement.scrollTop = 0;
2018-07-14 09:59:25 +00:00
},
2018-04-09 14:49:58 +00:00
},
2018-07-13 13:55:29 +00:00
2019-08-12 12:38:09 +00:00
render() {
2019-01-12 03:33:27 +00:00
const name = this.name;
const isCN = isZhCN(name);
const titleMap = {};
2018-04-09 14:49:58 +00:00
const menuConfig = {
General: [],
Layout: [],
Navigation: [],
'Data Entry': [],
'Data Display': [],
Feedback: [],
Other: [],
2019-01-12 03:33:27 +00:00
};
const pagesKey = [];
let prevPage = null;
let nextPage = null;
const searchData = [];
2018-04-09 14:49:58 +00:00
for (const [title, d] of Object.entries(AllDemo)) {
2019-01-12 03:33:27 +00:00
const type = d.type || 'Other';
const key = `${title.replace(/(\B[A-Z])/g, '-$1').toLowerCase()}`;
titleMap[key] = title;
AllDemo[title].key = key;
menuConfig[type] = menuConfig[type] || [];
menuConfig[type].push(d);
2018-04-09 14:49:58 +00:00
}
2019-01-12 03:33:27 +00:00
const docsMenu = this.getDocsMenu(isCN, pagesKey);
const reName = name.replace(/-cn\/?$/, '');
const MenuGroup = [];
2018-04-09 14:49:58 +00:00
for (const [type, menus] of Object.entries(menuConfig)) {
2019-01-12 03:33:27 +00:00
const MenuItems = [];
2018-07-14 09:10:50 +00:00
sortBy(menus, ['title']).forEach(({ title, subtitle }) => {
2018-04-09 14:49:58 +00:00
const linkValue = isCN
2019-08-12 12:38:09 +00:00
? [<span>{title}</span>, <span class="chinese">{subtitle}</span>]
2019-01-12 03:33:27 +00:00
: [<span>{title}</span>];
let key = `${title.replace(/(\B[A-Z])/g, '-$1').toLowerCase()}`;
2018-04-09 14:49:58 +00:00
if (isCN) {
2019-01-12 03:33:27 +00:00
key = `${key}-cn`;
2018-04-09 14:49:58 +00:00
}
2018-08-10 06:52:26 +00:00
pagesKey.push({
name: key,
2019-02-16 08:51:21 +00:00
url: `/components/${key}/`,
2018-08-10 06:52:26 +00:00
title: isCN ? `${title} ${subtitle}` : title,
2019-01-12 03:33:27 +00:00
});
2018-04-11 05:32:18 +00:00
searchData.push({
title,
subtitle,
2019-02-16 08:51:21 +00:00
url: `/components/${key}/`,
2019-01-12 03:33:27 +00:00
});
2019-08-12 12:38:09 +00:00
MenuItems.push(
<a-menu-item key={key}>
<router-link to={`/components/${key}/`}>{linkValue}</router-link>
</a-menu-item>,
);
2019-01-12 03:33:27 +00:00
});
MenuGroup.push(<a-menu-item-group title={type}>{MenuItems}</a-menu-item-group>);
2018-04-09 14:49:58 +00:00
}
2018-08-10 06:52:26 +00:00
pagesKey.forEach((item, index) => {
if (item.name === name) {
2019-01-12 03:33:27 +00:00
prevPage = pagesKey[index - 1];
nextPage = pagesKey[index + 1];
2018-08-10 06:52:26 +00:00
}
2019-01-12 03:33:27 +00:00
});
let locale = zhCN;
2018-04-09 14:49:58 +00:00
if (!isCN) {
2019-01-12 03:33:27 +00:00
locale = enUS;
2018-04-09 14:49:58 +00:00
}
2019-01-12 03:33:27 +00:00
const config = AllDemo[titleMap[reName]];
this.resetDocumentTitle(config, reName, isCN);
2019-01-16 03:26:56 +00:00
const { isMobile } = this;
2018-04-09 14:49:58 +00:00
return (
2019-08-12 12:38:09 +00:00
<div class="page-wrapper">
<Header searchData={searchData} name={name} />
2018-04-09 14:49:58 +00:00
<a-locale-provider locale={locale}>
2019-08-12 12:38:09 +00:00
<div class="main-wrapper">
2018-04-09 14:49:58 +00:00
<a-row>
2019-08-12 12:38:09 +00:00
{isMobile ? (
<MobileMenu ref="sidebar" wrapperClassName="drawer-wrapper">
<a-menu
class="aside-container menu-site"
selectedKeys={[name]}
defaultOpenKeys={['Components']}
inlineIndent={40}
mode="inline"
>
{docsMenu}
<a-sub-menu title={`Components(${searchData.length})`} key="Components">
{MenuGroup}
</a-sub-menu>
</a-menu>
</MobileMenu>
) : (
<a-col
ref="sidebar"
class="site-sidebar main-menu"
xxl={4}
xl={5}
lg={5}
md={6}
sm={8}
xs={12}
>
<a-affix>
<section class="main-menu-inner">
<Sponsors title={isCN ? '赞助商' : 'Sponsors'} />
<a-menu
class="aside-container menu-site"
selectedKeys={[name]}
defaultOpenKeys={['Components']}
inlineIndent={40}
mode="inline"
>
{docsMenu}
<a-sub-menu title={`Components(${searchData.length})`} key="Components">
{MenuGroup}
</a-sub-menu>
</a-menu>
</section>
</a-affix>
</a-col>
)}
2019-01-12 09:19:57 +00:00
<a-col xxl={20} xl={19} lg={19} md={18} sm={24} xs={24}>
2019-08-12 12:38:09 +00:00
<section class="main-container main-container-component">
2019-08-04 13:14:08 +00:00
<CarbonAds isMobile={isMobile} />
<GeektimeAds isMobile={isMobile} />
2019-08-12 12:38:09 +00:00
{!isMobile ? (
<div class="toc-affix" style="width: 150px;">
{this.getSubMenu(isCN)}
</div>
) : null}
{this.showDemo ? (
<Provider store={this.store} key={isCN ? 'cn' : 'en'}>
<router-view
class={`demo-cols-${config.cols || 2}`}
{...{
directives: [
{
name: 'mountedCallback',
value: this.mountedCallback,
},
],
}}
></router-view>
</Provider>
) : (
''
)}
{this.showApi ? (
<div class="markdown api-container" ref="doc">
<router-view
{...{
directives: [
{
name: 'mountedCallback',
value: this.mountedCallback,
},
],
}}
></router-view>
</div>
) : (
''
)}
2019-01-12 09:19:57 +00:00
</section>
2019-08-12 12:38:09 +00:00
<section class="prev-next-nav">
{prevPage ? (
<router-link class="prev-page" to={`${prevPage.url}`}>
<a-icon type="left" />
&nbsp;&nbsp;{prevPage.title}
</router-link>
) : (
''
)}
{nextPage ? (
<router-link class="next-page" to={`${nextPage.url}`}>
{nextPage.title}&nbsp;&nbsp;
<a-icon type="right" />
</router-link>
) : (
''
)}
2018-08-10 06:52:26 +00:00
</section>
2019-08-12 12:38:09 +00:00
<Footer ref="footer" isCN={isCN} />
2018-04-09 14:49:58 +00:00
</a-col>
</a-row>
</div>
</a-locale-provider>
2019-08-12 12:38:09 +00:00
{name.indexOf('back-top') === -1 ? <a-back-top /> : null}
{isCN && <Geektime isMobile={isMobile} />}
2018-04-09 14:49:58 +00:00
</div>
2019-01-12 03:33:27 +00:00
);
2018-04-09 14:49:58 +00:00
},
2019-01-12 03:33:27 +00:00
};
2018-04-09 14:49:58 +00:00
</script>