283 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Vue
		
	
	
			
		
		
	
	
			283 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Vue
		
	
	
| <script>
 | |
| import AllDemo from '../demo'
 | |
| import Header from './header'
 | |
| import Footer from './footer'
 | |
| 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'
 | |
| 
 | |
| 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: '国际化' },
 | |
| ]
 | |
| 
 | |
| export default {
 | |
|   props: {
 | |
|     name: String,
 | |
|     showDemo: Boolean,
 | |
|     showApi: Boolean,
 | |
|   },
 | |
|   data () {
 | |
|     this.store = create({
 | |
|       currentSubMenu: [],
 | |
|     })
 | |
|     this.subscribe()
 | |
|     return {
 | |
|       showSideBars: true,
 | |
|       currentSubMenu: [],
 | |
|       sidebarHeight: document.documentElement.offsetHeight,
 | |
|     }
 | |
|   },
 | |
|   provide () {
 | |
|     return {
 | |
|       demoContext: this,
 | |
|     }
 | |
|   },
 | |
|   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 () {
 | |
|     this.$nextTick(() => {
 | |
|       this.addSubMenu()
 | |
|       const nprogressHiddenStyle = document.getElementById('nprogress-style')
 | |
|       if (nprogressHiddenStyle) {
 | |
|         this.timer = setTimeout(() => {
 | |
|           nprogressHiddenStyle.parentNode.removeChild(nprogressHiddenStyle)
 | |
|         }, 0)
 | |
|       }
 | |
|     })
 | |
|   },
 | |
|   watch: {
 | |
|     '$route.path': function () {
 | |
|       this.store.setState({ currentSubMenu: [] })
 | |
|       this.addSubMenu()
 | |
|     },
 | |
|   },
 | |
|   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 }) => {
 | |
|         const title = isCN ? cnTitle : usTitle
 | |
|         lis.push(<a-anchor-link key={id} 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: `/ant-design-vue/docs/vue/${k}/`,
 | |
|           title: isCN ? title : enTitle,
 | |
|         })
 | |
|         docsMenu.push(<a-menu-item key={k}>
 | |
|           <router-link to={`/ant-design-vue/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: `/ant-design-vue/components/${key}/`,
 | |
|           title: isCN ? `${title} ${subtitle}` : title,
 | |
|         })
 | |
|         searchData.push({
 | |
|           title,
 | |
|           subtitle,
 | |
|           url: `/ant-design-vue/components/${key}/`,
 | |
|         })
 | |
|         MenuItems.push(<a-menu-item key={key}>
 | |
|           <router-link to={`/ant-design-vue/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 { showSideBars } = this
 | |
|     return (
 | |
|       <div class='page-wrapper'>
 | |
|         <Header searchData={searchData} name={name}/>
 | |
|         <a-locale-provider locale={locale}>
 | |
|           <div class='main-wrapper'>
 | |
|             <a-row>
 | |
|               <a-col v-show={showSideBars} ref='sidebar' class='site-sidebar' xxl={4} xl={5} lg={5} md={6} sm={8} xs={12}>
 | |
|                 <div class='drawer-mask' onClick={() => { this.showSideBars = false }}></div>
 | |
|                 <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>
 | |
|                 <div class='close-drawer' onClick={() => { this.showSideBars = false }}>
 | |
|                   <a-icon type='close'/>
 | |
|                 </div>
 | |
|               </a-col>
 | |
|               <div v-show={!showSideBars} class='open-drawer' onClick={() => { this.showSideBars = true }}>
 | |
|                 <a-icon type='bars'/>
 | |
|               </div>
 | |
|               <a-col class='main-container' xxl={20} xl={19} lg={19} md={18} sm={24} xs={24}>
 | |
|                 <div class='content'>
 | |
|                   <div class='toc-affix' style='width: 120px;'>
 | |
|                     {this.getSubMenu(isCN)}
 | |
|                   </div>
 | |
|                   {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> : ''}
 | |
|                 </div>
 | |
|                 <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>
 | |
|               </a-col>
 | |
|             </a-row>
 | |
|           </div>
 | |
|         </a-locale-provider>
 | |
|         <Footer ref='footer' isCN={isCN}/>
 | |
|         { name.indexOf('back-top') === -1 ? <a-back-top /> : null }
 | |
|       </div>
 | |
|     )
 | |
|   },
 | |
| }
 | |
| </script>
 |