提交 fa4751e2 编写于 作者: E Evan You

homepage

上级 e19cfe0f
......@@ -4,7 +4,7 @@ const { extractHeaders } = require('../../lib')
module.exports = {
title: 'VuePress',
description: 'Minimalistic docs generator with Vue component based layout system',
description: 'Vue-powered Static Site Generator',
dest: 'vuepress',
base,
head: [
......@@ -13,6 +13,7 @@ module.exports = {
themeConfig: {
logo: `${base}logo.png`,
repo: 'vuejs/vuepress',
editBase: 'https://github.com/vuejs/vuepress/tree/master/docs',
nav: [
{
text: 'Guide',
......
---
title: Home
home: true
heroImage: /hero.png
actionText: Get Started →
actionLink: /guide/
features:
- title: Writing First
details: Minimal setup with markdown-centered project structure helps you focus on writing.
- title: Vue-Powered
details: Enjoy the dev experience of Vue + webpack, use Vue components in markdown, and develop custom themes with Vue.
- title: Performant
details: VuePress generates pre-rendered static HTML for each page, and runs as an SPA once a page is loaded.
---
# VuePress
> VuePress is a minimalistic docs generator with a Vue component based layout system.
## Why
- **Writing First**: minimal setup, all you need is a markdown file.
- **Vue-powered**: Use custom Vue components inside markdown, and develop custom themes using Vue single file components.
- **Great Dev Experience**: enjoy the same enjoyable development experience of a Vue app. Leverage the full power of webpack (hot-reload, pre-processors), generate SEO-friendly static HTML, and works as an SPA after initial page load.
- **Optimized for Docs**: many [built-in markdown extensions](./markdown.md) and default theme features for writing great documentation.
- **GitHub Friendly**: source markdown files can link to each other using relative links that ends in `.md` so they are also readable on GitHub, auto-generates page edit links if a repo is provided.
# Configuration
# Config Reference
## Basic Config
......
import { pathToComponentName, getTitle, getLang } from './util'
import { pathToComponentName } from './util'
export default {
created () {
if (this.$ssrContext) {
this.$ssrContext.title = getTitle(this.$page)
this.$ssrContext.lang = getLang(this.$page)
}
},
functional: true,
beforeMount () {
this.currentMetaTags = []
const updateMeta = () => {
document.title = getTitle(this.$page)
document.documentElement.lang = getLang(this.$page)
this.currentMetaTags = updateMetaTags(this.$page, this.currentMetaTags)
props: {
custom: {
type: Boolean,
default: true
}
this.$watch('$page', updateMeta)
updateMeta()
},
beforeDestroy () {
updateMetaTags(null, this.currentMetaTags)
},
render (h) {
return h(pathToComponentName(this.$page.path))
}
}
function updateMetaTags (page, current) {
if (current) {
current.forEach(c => {
document.head.removeChild(c)
})
}
const data = page && page.frontmatter.meta
if (data) {
return data.map(m => {
const tag = document.createElement('meta')
Object.keys(m).forEach(key => {
tag.setAttribute(key, m[key])
})
document.head.appendChild(tag)
return tag
render (h, { parent, props }) {
return h(pathToComponentName(parent.$page.path), {
class: props.custom ? 'custom' : ''
})
}
}
<template>
<div class="home">
<div class="hero">
<img v-if="data.heroImage" :src="data.heroImage">
<h1>{{ data.heroText || $site.title }}</h1>
<p class="description">
{{ data.tagline || $site.description }}
</p>
<p class="action" v-if="data.actionText && data.actionLink">
<router-link class="action-button" :to="ensureExt(data.actionLink)">
{{ data.actionText }}
</router-link>
</p>
</div>
<div class="features">
<div class="feature" v-for="feature in data.features">
<h2>{{ feature.title }}</h2>
<p>{{ feature.details }}</p>
</div>
</div>
<Content custom/>
</div>
</template>
<script>
import { ensureExt } from './util'
export default {
methods: {
ensureExt
},
computed: {
data () {
return this.$page.frontmatter
}
}
}
</script>
<style lang="stylus">
@import './styles/config.stylus'
.home
padding $navbarHeight 2rem 0
max-width 960px
margin 0px auto
.hero
text-align center
img
max-height 15rem
display block
margin 3rem auto 1.5rem
h1
font-size 3rem
h1, .description, .action
margin 1.8rem auto
.description
max-width 35rem
font-size 1.6rem
line-height 1.3
color lighten($textColor, 40%)
.action-button
display inline-block
font-size 1.2rem
color #fff
background-color $accentColor
padding 0.8rem 1.6rem
border-radius 4px
transition background-color .1s ease
box-sizing border-box
border-bottom 1px solid darken($accentColor, 10%)
&:hover
background-color lighten($accentColor, 10%)
.features
border-top 1px solid $borderColor
padding 1.2rem 0
margin-top 2.5rem
display flex
flex-wrap wrap
align-items flex-start
align-content strech
justify-content space-between
.feature
flex-grow 1
flex-basis 30%
max-width 30%
h2
font-size 1.4rem
font-weight 500
border-bottom none
padding-bottom 0
color lighten($textColor, 10%)
p
color lighten($textColor, 25%)
@media (max-width: $MQMobile)
.home
.features
flex-direction column
.feature
max-width 100%
padding 0 2.5rem
@media (max-width: $MQMobileNarrow)
.home
.hero
img
max-height 10rem
margin 2rem auto 1.2rem
h1
font-size 2rem
h1, .description, .action
margin 1.2rem auto
.description
font-size 1.2rem
.action-button
font-size 1rem
padding 0.6rem 1.2rem
.feature
h2
font-size 1.25rem
</style>
<template>
<div class="theme-container"
:class="{ 'sidebar-open': isSidebarOpen }"
:class="{
'sidebar-open': isSidebarOpen,
'no-sidebar': $page.frontmatter.home || $page.frontmatter.sidebar === false
}"
@touchstart="onTouchStart"
@touchend="onTouchEnd">
<Navbar @toggle-sidebar="toggleSidebar"/>
<Sidebar @toggle-sidebar="toggleSidebar"/>
<Page/>
<div class="custom-layout" v-if="$page.frontmatter.layout">
<component :is="$page.frontmatter.layout"/>
</div>
<Home v-else-if="$page.frontmatter.home"/>
<Page v-else/>
</div>
</template>
<script>
import Vue from 'vue'
import nprogress from 'nprogress'
import Home from './Home.vue'
import Navbar from './Navbar.vue'
import Page from './Page.vue'
import Sidebar from './Sidebar.vue'
import { pathToComponentName } from '../app/util'
import { pathToComponentName, getTitle, getLang } from '../app/util'
export default {
components: { Page, Sidebar, Navbar },
components: { Home, Page, Sidebar, Navbar },
data () {
return {
isSidebarOpen: false
}
},
created () {
if (this.$ssrContext) {
this.$ssrContext.title = getTitle(this.$page)
this.$ssrContext.lang = getLang(this.$page)
}
},
mounted () {
// update title / meta tags
this.currentMetaTags = []
const updateMeta = () => {
document.title = getTitle(this.$page)
document.documentElement.lang = getLang(this.$page)
this.currentMetaTags = updateMetaTags(this.$page, this.currentMetaTags)
}
this.$watch('$page', updateMeta)
updateMeta()
// configure progress bar
nprogress.configure({ showSpinner: false })
this.$router.beforeEach((to, from, next) => {
......@@ -39,6 +66,11 @@ export default {
this.isSidebarOpen = false
})
},
beforeDestroy () {
updateMetaTags(null, this.currentMetaTags)
},
methods: {
toggleSidebar (to) {
this.isSidebarOpen = typeof to === 'boolean' ? to : !this.isSidebarOpen
......@@ -63,6 +95,25 @@ export default {
}
}
}
function updateMetaTags (page, current) {
if (current) {
current.forEach(c => {
document.head.removeChild(c)
})
}
const data = page && page.frontmatter.meta
if (data) {
return data.map(m => {
const tag = document.createElement('meta')
Object.keys(m).forEach(key => {
tag.setAttribute(key, m[key])
})
document.head.appendChild(tag)
return tag
})
}
}
</script>
<style src="prismjs/themes/prism-tomorrow.css"></style>
......
<template>
<div class="nav-links">
<!-- user links -->
<router-link v-for="item in userLinks" :to="item.link">
<router-link v-for="item in userLinks"
:to="item.link"
:key="item.link"
:class="{ active: isActive($route, item.link) }">
{{ item.text }}
</router-link>
<!-- github link -->
......@@ -19,7 +22,7 @@
</template>
<script>
import { ensureExt } from './util'
import { isActive, ensureExt } from './util'
export default {
computed: {
......@@ -37,14 +40,27 @@ export default {
: `https://github.com/${repo}`
}
}
},
methods: {
isActive
}
}
</script>
<style lang="stylus">
.github-link .icon
color #aaa
display inline-block
position relative
top .1rem
@import './styles/config.stylus'
.nav-links
a
color inherit
font-weight 500
line-height 1.5
&:hover, &.active
margin-bottom -2px
border-bottom 2px solid lighten($accentColor, 10%)
.github-link .icon
color #aaa
display inline-block
position relative
top .1rem
</style>
......@@ -36,10 +36,6 @@ export default {
a, span, img
vertical-align middle
display inline-block
a
font-weight 600
&:hover
text-decoration underline
.logo
display inline-block
height 2rem
......
<template>
<div class="page">
<Content/>
<Content :custom="false"/>
<div class="content page-nav" v-if="prev || next">
<p>
<p class="inner">
<span v-if="prev" class="prev">
<router-link v-if="prev" class="prev" :to="prev.path">
{{ prev.title || prev.path }}
......@@ -39,10 +39,10 @@ export default {
@import './styles/config.stylus'
.page-nav.content
padding-top 0
min-height 2.2rem
p
margin 0
padding-bottom 2rem
.inner
margin-top 0 !important
border-top 1px solid $borderColor
padding-top 1rem
.next
......
......@@ -18,10 +18,10 @@
<script>
import SidebarGroup from './SidebarGroup.vue'
import SidebarLink, { isActive } from './SidebarLink.vue'
import SidebarLink from './SidebarLink.vue'
import SidebarButton from './SidebarButton.vue'
import NavLinks from './NavLinks.vue'
import { resolvePage } from './util'
import { resolvePage, isActive } from './util'
export default {
components: { SidebarGroup, SidebarLink, SidebarButton, NavLinks },
......@@ -60,7 +60,7 @@ export default {
this.openGroupIndex = index === this.openGroupIndex ? -1 : index
},
isActive (page) {
return isActive(this.$route, page)
return isActive(this.$route, page.path)
}
}
}
......@@ -68,7 +68,7 @@ export default {
function resolveOpenGroupIndex (route, items) {
for (let i = 0; i < items.length; i++) {
const item = items[i]
if (item.type === 'group' && item.children.some(c => isActive(route, c))) {
if (item.type === 'group' && item.children.some(c => isActive(route, c.path))) {
return i
}
}
......
<script>
import { normalize, getHash, ensureExt } from './util'
import { isActive } from './util'
export default {
functional: true,
......@@ -13,28 +13,11 @@ export default {
'sidebar-link': true,
// use custom active class matching logic
// due to edge case of paths ending with / + hash
active: isActive($route, item)
active: isActive($route, item.path)
}
}, [item.title || item.path])
}
}
const endingSlashRE = /\/$/
export function isActive (route, page) {
const routeHash = route.hash
const linkHash = getHash(page.path)
if (linkHash && routeHash !== linkHash) {
return false
}
const routePath = normalize(route.path)
const pagePath = normalize(page.path)
if (endingSlashRE.test(routePath) || endingSlashRE.test(pagePath)) {
return routePath === pagePath
} else {
return routePath.indexOf(pagePath) === 0
}
}
</script>
<style lang="stylus">
......
......@@ -3,7 +3,7 @@
p, h1, h2, h3, h4, h5, h6
code
color lighten($textColor, 20%)
padding 0.2rem 0.5rem
padding 0.25rem 0.5rem
margin 0
font-size 0.85rem
background-color rgba(27,31,35,0.05)
......@@ -15,6 +15,7 @@ pre, pre[class*="language-"]
line-height 1.4
border-radius 6px
padding 1.25rem 1.5rem
margin 0.85rem 0
white-space pre-wrap
word-break break-word
overflow auto
......
......@@ -11,7 +11,7 @@ $mobileSidebarWidth = $sidebarWidth * 0.82
width $mobileSidebarWidth
.page
padding-left $mobileSidebarWidth
.content
.content:not(.custom)
padding 2rem
// wide mobile
......@@ -30,7 +30,7 @@ $mobileSidebarWidth = $sidebarWidth * 0.82
// narrow mobile
@media (max-width: $MQMobileNarrow)
pre, pre[class*="language-"]
margin 0 -1.5rem
margin 0.85rem -1.5rem
border-radius 0
.content
.content:not(.custom)
padding 1.5rem
......@@ -44,7 +44,7 @@ body
border-right 1px solid $borderColor
overflow-y scroll
.content
.content:not(.custom)
max-width $contentWidth
margin 0 auto
padding 2rem 2.5rem
......@@ -53,6 +53,10 @@ body
a:hover
text-decoration underline
.content.custom
padding 0
margin 0
a
font-weight 500
color $accentColor
......@@ -78,12 +82,13 @@ strong
h1, h2, h3, h4, h5, h6
font-weight 600
line-height 1.25
margin-top (0.5rem - $navbarHeight)
padding-top ($navbarHeight + 1rem)
margin-bottom 0
.content &
.content:not(.custom) &
margin-top (0.5rem - $navbarHeight)
padding-top ($navbarHeight + 1rem)
margin-bottom 0
&:first-child
margin-top -1.5rem
margin-bottom 1rem
&:hover .header-anchor
opacity: 1
......@@ -120,4 +125,12 @@ p
border 1px solid #ddd
border-radius 4px
.custom-layout
padding-top $navbarHeight
@media (min-width: ($MQMobile + 1px))
.theme-container.no-sidebar
.sidebar
display none
@import './mobile.stylus'
......@@ -30,6 +30,21 @@ export function ensureExt (path) {
return normalized + '.html' + hash
}
export function isActive (route, path) {
const routeHash = route.hash
const linkHash = getHash(path)
if (linkHash && routeHash !== linkHash) {
return false
}
const routePath = normalize(route.path)
const pagePath = normalize(path)
if (endingSlashRE.test(routePath) || endingSlashRE.test(pagePath)) {
return routePath === pagePath
} else {
return routePath.indexOf(pagePath) === 0
}
}
export function resolvePage (pages, rawPath, base) {
if (base) {
rawPath = resolvePath(rawPath, base)
......
......@@ -32,7 +32,7 @@ module.exports = function (src) {
const { html, hoistedTags } = markdown.renderWithHoisting(content)
return (
`<template>\n` +
`<div class="markdown content">${html}</div>\n` +
`<div class="content">${html}</div>\n` +
`</template>\n` +
hoistedTags.join('\n')
)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册