provide siteData to theme

pull/1/head
Evan You 4 years ago
parent 13924c9734
commit 982501fd30

@ -1,7 +1,8 @@
import { h, shallowRef, watchEffect, inject, nextTick } from 'vue' import { h, shallowRef, watchEffect, inject, nextTick } from 'vue'
import { RouteSymbol } from './router' import { RouteSymbol } from '../composables/router'
import Theme from '/@theme/index'
const Default404 = () => '404 Not Found' const NotFound = Theme.NotFound || (() => '404 Not Found')
export const Content = { export const Content = {
setup() { setup() {
@ -35,7 +36,7 @@ export const Content = {
}) })
.catch((err) => { .catch((err) => {
if (route.path === pendingPath) { if (route.path === pendingPath) {
comp.value = Default404 comp.value = NotFound
} }
}) })
}) })

@ -0,0 +1,11 @@
export function useSiteData() {
return {
msg: 'this is site'
}
}
export function usePageData() {
return {
msg: 'this is page'
}
}

@ -0,0 +1,3 @@
// exports in this file are exposed to themes and md files via 'vitepress'
// so the user can do `import { usePageData } from 'vitepress'`
export { usePageData, useSiteData } from './composables/data'

@ -1,7 +1,8 @@
import { createApp, h } from 'vue' import { createApp, h } from 'vue'
import { Layout } from '/@theme/index' import { Content } from './components/Content'
import { Content } from './Content' import { useRouter } from './composables/router'
import { useRouter } from './router' import { useSiteData } from './composables/data'
import Theme from '/@theme/index'
const App = { const App = {
setup() { setup() {
@ -10,12 +11,16 @@ const App = {
} else { } else {
// TODO inject static route for SSR // TODO inject static route for SSR
} }
return () => h(Layout) return () => h(Theme.Layout)
} }
} }
const app = createApp(App) const app = createApp(App)
Object.defineProperty(app.config.globalProperties, '$site', {
get: useSiteData
})
app.component('Content', Content) app.component('Content', Content)
app.mount('#app') app.mount('#app')

@ -1,5 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"baseUrl": "../",
"lib": ["ESNext", "DOM"], "lib": ["ESNext", "DOM"],
"moduleResolution": "node", "moduleResolution": "node",
"checkJs": true, "checkJs": true,
@ -8,7 +9,8 @@
"noImplicitAny": true, "noImplicitAny": true,
"paths": { "paths": {
"/@app/*": ["lib/app/*"], "/@app/*": ["lib/app/*"],
"/@theme/*": ["lib/theme-default/*"] "/@theme/*": ["lib/theme-default/*"],
"vitepress": ["lib/app/exports.js"]
} }
}, },
"include": ["."] "include": ["."]

@ -1,13 +1,22 @@
<template> <template>
<div class="theme-container"> <div class="theme-container">
<h1>Hello VitePress {{ a }}</h1> <h1>Hello VitePress</h1>
<pre>{{ $site }}</pre>
<pre>{{ $page }}</pre>
<pre>{{ site }}</pre>
<pre>{{ page }}</pre>
<Content/> <Content/>
</div> </div>
</template> </template>
<script> <script>
import { useSiteData, usePageData } from 'vitepress'
export default { export default {
data: () => ({ a: 111 }) data: () => ({
site: useSiteData(),
page: usePageData()
})
} }
</script> </script>

@ -1,3 +1,13 @@
import Layout from './Layout.vue' import Layout from './Layout.vue'
export { Layout } /**
* @type {{
* Layout: import('vue').ComponentOptions
* NotFound?: import('vue').ComponentOptions
* }}
*/
const Theme = {
Layout
}
export default Theme

@ -38,7 +38,7 @@ function createVitePressPlugin({
app.use(async (ctx, next) => { app.use(async (ctx, next) => {
// handle .md -> vue transforms // handle .md -> vue transforms
if (ctx.path.endsWith('.md')) { if (ctx.path.endsWith('.md')) {
const file = resolver.publicToFile(ctx.path) const file = resolver.requestToFile(ctx.path)
await cachedRead(ctx, file) await cachedRead(ctx, file)
// let vite know this is supposed to be treated as vue file // let vite know this is supposed to be treated as vue file
ctx.vue = true ctx.vue = true
@ -48,7 +48,7 @@ function createVitePressPlugin({
} }
// detect and serve vitepress @app / @theme files // detect and serve vitepress @app / @theme files
const file = vitepressResolver.publicToFile(ctx.path, root) const file = vitepressResolver.requestToFile(ctx.path, root)
if (file) { if (file) {
await cachedRead(ctx, file) await cachedRead(ctx, file)
debug(ctx.url, ctx.status) debug(ctx.url, ctx.status)

@ -1,6 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"baseUrl": ".", "baseUrl": "../",
"outDir": "../dist", "outDir": "../dist",
"module": "commonjs", "module": "commonjs",
"lib": ["ESNext"], "lib": ["ESNext"],

@ -10,7 +10,7 @@ export const APP_PATH = path.join(__dirname, '../../lib/app')
// vite HMR can send the correct update notifications to the client. // vite HMR can send the correct update notifications to the client.
export function createResolver(themePath: string): Resolver { export function createResolver(themePath: string): Resolver {
return { return {
publicToFile(publicPath) { requestToFile(publicPath) {
if (publicPath.startsWith('/@app')) { if (publicPath.startsWith('/@app')) {
return path.join(APP_PATH, publicPath.replace(/^\/@app\/?/, '')) return path.join(APP_PATH, publicPath.replace(/^\/@app\/?/, ''))
} }
@ -18,13 +18,18 @@ export function createResolver(themePath: string): Resolver {
return path.join(themePath, publicPath.replace(/^\/@theme\/?/, '')) return path.join(themePath, publicPath.replace(/^\/@theme\/?/, ''))
} }
}, },
fileToPublic(filePath) { fileToRequest(filePath) {
if (filePath.startsWith(APP_PATH)) { if (filePath.startsWith(APP_PATH)) {
return `/@app/${path.relative(APP_PATH, filePath)}` return `/@app/${path.relative(APP_PATH, filePath)}`
} }
if (filePath.startsWith(themePath)) { if (filePath.startsWith(themePath)) {
return `/@theme/${path.relative(themePath, filePath)}` return `/@theme/${path.relative(themePath, filePath)}`
} }
},
idToRequest(id) {
if (id === 'vitepress') {
return '/@app/exports.js'
}
} }
} }
} }

Loading…
Cancel
Save