You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
368 lines
12 KiB
368 lines
12 KiB
<script>
|
|
import { enquireScreen } from 'enquire-js';
|
|
import AllDemo from '../demo';
|
|
import Header from './header';
|
|
import Footer from './footer';
|
|
import CarbonAds from './CarbonAds';
|
|
import Geektime from './geektime';
|
|
import GeektimeAds from './geektime_ads';
|
|
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';
|
|
import MobileMenu from '../../components/vc-drawer/src';
|
|
import GoogleAdsTop from './GoogleAdsTop';
|
|
import GoogleAds from './GoogleAds';
|
|
|
|
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: '国际化' },
|
|
{ key: 'faq', enTitle: 'FAQ', title: '常见问题' },
|
|
{ key: 'sponsor', enTitle: 'Sponsor', title: '支持我们' },
|
|
{ key: 'download', enTitle: 'Download Design Resources', title: '下载设计资源' },
|
|
];
|
|
|
|
const isGitee = window.location.host.indexOf('gitee.io') > -1;
|
|
const showAd = location.host.indexOf('antdv.com') > -1;
|
|
export default {
|
|
props: {
|
|
name: String,
|
|
showDemo: Boolean,
|
|
showApi: Boolean,
|
|
},
|
|
data() {
|
|
this.store = create({
|
|
currentSubMenu: [],
|
|
});
|
|
this.subscribe();
|
|
return {
|
|
showSideBars: true,
|
|
currentSubMenu: [],
|
|
sidebarHeight: document.documentElement.offsetHeight,
|
|
isMobile: false,
|
|
};
|
|
},
|
|
provide() {
|
|
return {
|
|
demoContext: this,
|
|
};
|
|
},
|
|
watch: {
|
|
'$route.path': function() {
|
|
this.store.setState({ currentSubMenu: [] });
|
|
this.addSubMenu();
|
|
},
|
|
},
|
|
beforeDestroy() {
|
|
if (this.unsubscribe) {
|
|
this.unsubscribe();
|
|
}
|
|
clearTimeout(this.timer);
|
|
if (this.resizeEvent) {
|
|
this.resizeEvent.remove();
|
|
}
|
|
if (this.debouncedResize && this.debouncedResize.cancel) {
|
|
this.debouncedResize.cancel();
|
|
}
|
|
},
|
|
mounted() {
|
|
if (isGitee) {
|
|
this.$info({
|
|
title: '提示',
|
|
content: '访问国内镜像站点的用户请访问 antdv.com 站点',
|
|
okText: '立即跳转',
|
|
onOk() {
|
|
location.href = 'https://www.antdv.com';
|
|
},
|
|
});
|
|
}
|
|
|
|
this.$nextTick(() => {
|
|
this.addSubMenu();
|
|
const nprogressHiddenStyle = document.getElementById('nprogress-style');
|
|
if (nprogressHiddenStyle) {
|
|
this.timer = setTimeout(() => {
|
|
nprogressHiddenStyle.parentNode.removeChild(nprogressHiddenStyle);
|
|
}, 0);
|
|
}
|
|
enquireScreen(b => {
|
|
this.isMobile = !!b;
|
|
});
|
|
});
|
|
},
|
|
methods: {
|
|
addSubMenu() {
|
|
if (this.$route.path.indexOf('/docs/vue/') !== -1) {
|
|
this.$nextTick(() => {
|
|
const menus = [];
|
|
const doms = [...this.$refs.doc.querySelectorAll(['h2', 'h3'])];
|
|
doms.forEach(dom => {
|
|
const id = dom.id;
|
|
if (id) {
|
|
const title = dom.textContent.split('#')[0].trim();
|
|
menus.push({ cnTitle: title, usTitle: title, id });
|
|
}
|
|
});
|
|
this.currentSubMenu = menus;
|
|
});
|
|
}
|
|
},
|
|
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 }, index) => {
|
|
const title = isCN ? cnTitle : usTitle;
|
|
lis.push(<a-anchor-link key={id + index} href={`#${id}`} title={title} />);
|
|
});
|
|
const showApi = this.$route.path.indexOf('/components/') !== -1;
|
|
return (
|
|
<a-anchor offsetTop={100} class="demo-anchor">
|
|
{lis}
|
|
{showApi ? <a-anchor-link key="API" title="API" href="#api" /> : ''}
|
|
</a-anchor>
|
|
);
|
|
},
|
|
getDocsMenu(isCN, pagesKey) {
|
|
const docsMenu = [];
|
|
docsList.forEach(({ key, enTitle, title }, index) => {
|
|
const k = isCN ? `${key}-cn` : key;
|
|
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>,
|
|
);
|
|
});
|
|
return docsMenu;
|
|
},
|
|
resetDocumentTitle(component, name, isCN) {
|
|
let titleStr = 'Ant Design Vue';
|
|
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;
|
|
},
|
|
mountedCallback() {
|
|
NProgress.done();
|
|
document.documentElement.scrollTop = 0;
|
|
},
|
|
},
|
|
|
|
render() {
|
|
const name = this.name;
|
|
const isCN = isZhCN(name);
|
|
const titleMap = {};
|
|
const menuConfig = {
|
|
General: [],
|
|
Layout: [],
|
|
Navigation: [],
|
|
'Data Entry': [],
|
|
'Data Display': [],
|
|
Feedback: [],
|
|
Other: [],
|
|
};
|
|
const pagesKey = [];
|
|
let prevPage = null;
|
|
let nextPage = null;
|
|
const searchData = [];
|
|
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;
|
|
AllDemo[title].key = key;
|
|
menuConfig[type] = menuConfig[type] || [];
|
|
menuConfig[type].push(d);
|
|
}
|
|
const docsMenu = this.getDocsMenu(isCN, pagesKey);
|
|
const reName = name.replace(/-cn\/?$/, '');
|
|
const MenuGroup = [];
|
|
for (const [type, menus] of Object.entries(menuConfig)) {
|
|
const MenuItems = [];
|
|
sortBy(menus, ['title']).forEach(({ title, subtitle }) => {
|
|
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`;
|
|
}
|
|
pagesKey.push({
|
|
name: key,
|
|
url: `/components/${key}/`,
|
|
title: isCN ? `${title} ${subtitle}` : title,
|
|
});
|
|
searchData.push({
|
|
title,
|
|
subtitle,
|
|
url: `/components/${key}/`,
|
|
});
|
|
MenuItems.push(
|
|
<a-menu-item key={key}>
|
|
<router-link to={`/components/${key}/`}>{linkValue}</router-link>
|
|
</a-menu-item>,
|
|
);
|
|
});
|
|
MenuGroup.push(<a-menu-item-group title={type}>{MenuItems}</a-menu-item-group>);
|
|
}
|
|
pagesKey.forEach((item, index) => {
|
|
if (item.name === name) {
|
|
prevPage = pagesKey[index - 1];
|
|
nextPage = pagesKey[index + 1];
|
|
}
|
|
});
|
|
let locale = zhCN;
|
|
if (!isCN) {
|
|
locale = enUS;
|
|
}
|
|
const config = AllDemo[titleMap[reName]];
|
|
this.resetDocumentTitle(config, reName, isCN);
|
|
const { isMobile, $route } = this;
|
|
return (
|
|
<div class="page-wrapper">
|
|
<Header searchData={searchData} name={name} />
|
|
<a-config-provider locale={locale}>
|
|
<div class="main-wrapper">
|
|
<a-row>
|
|
{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 isCN={isCN} />
|
|
<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>
|
|
)}
|
|
<a-col xxl={20} xl={19} lg={19} md={18} sm={24} xs={24}>
|
|
<section class="main-container main-container-component">
|
|
{showAd ? <GoogleAdsTop key={`GoogleAdsTop_${$route.path}`} /> : null}
|
|
{!isMobile ? <CarbonAds /> : null}
|
|
{showAd ? <GeektimeAds isMobile={isMobile} /> : null}
|
|
{!isMobile ? (
|
|
<div class={['toc-affix', isCN ? 'toc-affix-cn' : '']} 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>
|
|
{showAd ? <GoogleAds key={`GoogleAds_${$route.path}`} /> : null}
|
|
</div>
|
|
) : (
|
|
''
|
|
)}
|
|
</section>
|
|
<section class="prev-next-nav">
|
|
{prevPage ? (
|
|
<router-link class="prev-page" to={`${prevPage.url}`}>
|
|
<a-icon type="left" />
|
|
{prevPage.title}
|
|
</router-link>
|
|
) : (
|
|
''
|
|
)}
|
|
{nextPage ? (
|
|
<router-link class="next-page" to={`${nextPage.url}`}>
|
|
{nextPage.title}
|
|
<a-icon type="right" />
|
|
</router-link>
|
|
) : (
|
|
''
|
|
)}
|
|
</section>
|
|
<Footer ref="footer" isCN={isCN} />
|
|
</a-col>
|
|
</a-row>
|
|
</div>
|
|
</a-config-provider>
|
|
{name.indexOf('back-top') === -1 ? <a-back-top /> : null}
|
|
{isCN && <Geektime isMobile={isMobile} />}
|
|
</div>
|
|
);
|
|
},
|
|
};
|
|
</script>
|