Skip to content

Commit

Permalink
refactor router/content
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Apr 28, 2020
1 parent c4002a8 commit 96c30a6
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 59 deletions.
48 changes: 4 additions & 44 deletions lib/app/components/Content.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,9 @@
import { h, shallowRef, watchEffect, inject, nextTick } from 'vue'
import { RouteSymbol } from '../composables/router'
import Theme from '/@theme/index'

const NotFound = Theme.NotFound || (() => '404 Not Found')
import { h } from 'vue'
import { useRoute } from '../composables/router'

export const Content = {
setup() {
const comp = shallowRef()

if (typeof window !== 'undefined') {
const route = inject(RouteSymbol, {
path: '/',
scrollPosition: 0
})

watchEffect(() => {
const pendingPath = route.path
let pagePath = pendingPath.replace(/\.html$/, '')
if (pagePath.endsWith('/')) {
pagePath += 'index'
}

// awlays force re-fetch content in dev
import(`${pagePath}.md?t=${Date.now()}`)
.then(async (m) => {
if (route.path === pendingPath) {
comp.value = m.default
await nextTick()
window.scrollTo({
left: 0,
top: route.scrollPosition,
behavior: 'auto'
})
}
})
.catch((err) => {
if (route.path === pendingPath) {
comp.value = NotFound
}
})
})
} else {
// TODO SSR
}

return () => (comp.value ? h(comp.value) : null)
const route = useRoute()
return () => (route.component ? h(route.component) : null)
}
}
72 changes: 61 additions & 11 deletions lib/app/composables/router.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
import { reactive, provide } from 'vue'
import { shallowReactive, provide, inject, nextTick } from 'vue'
import Theme from '/@theme/index'

const NotFound = Theme.NotFound || (() => '404 Not Found')

/**
* @type {import('vue').InjectionKey<{ path: string, scrollPosition: number }>}
* @typedef {{
* path: string
* component: import('vue').Component | null
* }} Route
*/
export const RouteSymbol = Symbol()

/**
* @type {import('vue').InjectionKey<Route>}
*/
const RouteSymbol = Symbol()

/**
* @returns {Route}
*/
const getDefaultRoute = () => ({
path: location.pathname,
component: null
})

export function useRouter() {
const loc = location
const route = reactive({
path: loc.pathname,
scrollPosition: window.scrollY
})
const route = shallowReactive(getDefaultRoute())

window.addEventListener(
'click',
Expand Down Expand Up @@ -41,8 +56,7 @@ export function useRouter() {
// save scroll position before changing url
saveScrollPosition()
history.pushState(null, '', href)
route.path = loc.pathname
route.scrollPosition = 0
loadPage(route)
}
}
}
Expand All @@ -56,12 +70,48 @@ export function useRouter() {
* @param {*} e
*/
(e) => {
route.path = location.pathname
route.scrollPosition = (e.state && e.state.scrollPosition) || 0
loadPage(route, (e.state && e.state.scrollPosition) || 0)
}
)

provide(RouteSymbol, route)

loadPage(route)
}

export function useRoute() {
return inject(RouteSymbol) || getDefaultRoute()
}

/**
* @param {Route} route
* @param {number} scrollPosition
*/
function loadPage(route, scrollPosition = 0) {
const pendingPath = (route.path = location.pathname)
let pagePath = pendingPath.replace(/\.html$/, '')
if (pagePath.endsWith('/')) {
pagePath += 'index'
}

// awlays force re-fetch content in dev
import(`${pagePath}.md?t=${Date.now()}`)
.then(async (m) => {
if (route.path === pendingPath) {
route.component = m.default
await nextTick()
window.scrollTo({
left: 0,
top: scrollPosition,
behavior: 'auto'
})
}
})
.catch((err) => {
if (route.path === pendingPath) {
route.component = NotFound
}
})
}

function saveScrollPosition() {
Expand Down
8 changes: 4 additions & 4 deletions lib/theme-default/Layout.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<template>
<div class="theme-container">
<h1>Hello VitePress</h1>
<pre>{{ $site }}</pre>
<pre>{{ $page }}</pre>
<pre>{{ site }}</pre>
<pre>{{ page }}</pre>
<pre>$site {{ $site }}</pre>
<pre>$page {{ $page }}</pre>
<pre>useSiteData() {{ site }}</pre>
<pre>usePageData() {{ page }}</pre>
<Content/>
</div>
</template>
Expand Down

0 comments on commit 96c30a6

Please sign in to comment.