Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d50dbf7

Browse files
setup tutorial src markdown support
1 parent 0f3b06b commit d50dbf7

File tree

21 files changed

+211
-43
lines changed

21 files changed

+211
-43
lines changed

β€Ž.gitignoreβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,4 @@ temp/
107107
TODOs.md
108108
src/api/index.json
109109
src/examples/data.json
110+
src/tutorial/data.json

β€Žpackage.jsonβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
"devDependencies": {
1313
"@types/node": "^16.9.1",
1414
"cheap-watch": "^1.0.3",
15-
"vitepress": "^0.20.2"
15+
"vitepress": "^0.20.4"
1616
}
1717
}

β€Žpnpm-lock.yamlβ€Ž

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

β€Žscripts/genExamplesData.jsβ€Ž

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ exports.genExamplesData = () => {
1515
})
1616
}
1717

18+
exports.readExample = readExample
19+
1820
function genExamples() {
1921
const srcDir = path.resolve(__dirname, '../src/examples/src')
2022
const examples = fs.readdirSync(srcDir)

β€Žscripts/genTutorialData.jsβ€Ž

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* watch / generate an all-tutorial data temporary json file (ignored by Git)
3+
*/
4+
5+
// @ts-check
6+
const fs = require('fs')
7+
const path = require('path')
8+
const { watch } = require('./watch')
9+
const { readExample } = require('./genExamplesData')
10+
const { createMarkdownRenderer } = require('vitepress')
11+
12+
exports.genTutorialData = () => {
13+
const md = createMarkdownRenderer(process.cwd())
14+
15+
watch({
16+
src: 'tutorial/src',
17+
out: 'tutorial/data.json',
18+
genData: () => genTutorialSteps(md)
19+
})
20+
}
21+
22+
/**
23+
* @param {import('vitepress').MarkdownRenderer} md
24+
*/
25+
function genTutorialSteps(md) {
26+
const srcDir = path.resolve(__dirname, '../src/tutorial/src')
27+
const steps = fs.readdirSync(srcDir).sort()
28+
const data = {}
29+
30+
for (const name of steps) {
31+
const step = readExample(path.join(srcDir, name))
32+
const desc = step['description.md']
33+
if (desc) {
34+
step['description.md'] = md.render(desc).html
35+
}
36+
37+
data[name] = step
38+
}
39+
return data
40+
}

β€Žsrc/.vitepress/config.jsβ€Ž

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ const fs = require('fs')
33
const path = require('path')
44
const { genApiIndex } = require('../../scripts/genApiIndex')
55
const { genExamplesData } = require('../../scripts/genExamplesData')
6-
const { headerPlugin } = require('./header')
6+
const { genTutorialData } = require('../../scripts/genTutorialData')
7+
const { headerPlugin } = require('./headerMdPlugin')
78

89
const nav = [
910
{
@@ -460,11 +461,11 @@ const sidebar = {
460461
text: 'Tutorial',
461462
items: [
462463
{
463-
text: '1. Hello World',
464+
text: '1. Adding Data',
464465
link: '/tutorial/#step-1'
465466
},
466467
{
467-
text: '2. Render a List',
468+
text: '2. Two-way Binding',
468469
link: '/tutorial/#step-2'
469470
}
470471
]
@@ -474,6 +475,7 @@ const sidebar = {
474475

475476
genApiIndex(sidebar['/api/'])
476477
genExamplesData()
478+
genTutorialData()
477479

478480
/**
479481
* @type {import('vitepress').UserConfig}
File renamed without changes.

β€Žsrc/.vitepress/theme/components/PreferenceSwitch.vueβ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
1212
const route = useRoute()
1313
const show = computed(() => /^\/(guide|tutorial|examples)\//.test(route.path))
14+
const showSFC = computed(() => !/^\/guide/.test(route.path))
1415
const isOpen = ref(
1516
typeof localStorage !== 'undefined' &&
1617
!localStorage.getItem(preferCompositionKey)
@@ -79,7 +80,7 @@ function useToggleFn(
7980
@click="closeSideBar"
8081
>?</a>
8182
</div>
82-
<div class="switch-container" v-if="route.path.startsWith('/examples')">
83+
<div class="switch-container" v-if="showSFC">
8384
<label class="no-sfc-label" @click="toggleSFC(false)">HTML</label>
8485
<VTSwitch
8586
class="sfc-switch"

β€Žsrc/examples/ExampleRepl.vueβ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Repl, ReplStore } from '@vue/repl'
33
import '@vue/repl/style.css'
44
import data from './data.json'
55
import { inject, watchEffect, version, Ref } from 'vue'
6-
import { resolveSFCExample, resolveNoBuildExample } from './utils'
6+
import { resolveSFCExample, resolveNoBuildExample, onHashChange } from './utils'
77
88
const store = new ReplStore({
99
defaultVueRuntimeURL: `https://unpkg.com/vue@${version}/dist/vue.esm-browser.js`
@@ -13,7 +13,7 @@ const preferComposition = inject('prefer-composition') as Ref<boolean>
1313
const preferSFC = inject('prefer-sfc') as Ref<boolean>
1414
1515
watchEffect(updateExample)
16-
window.addEventListener('hashchange', updateExample)
16+
onHashChange(updateExample)
1717
1818
/**
1919
* We perform some runtime logic to transform source files into different

β€Žsrc/examples/utils.tsβ€Ž

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { onBeforeUnmount } from 'vue'
2+
13
type ExampleData = {
24
[key: string]: Record<string, string>
35
} & {
@@ -66,7 +68,7 @@ function forEachComponent(
6668
) {
6769
for (const filename in raw) {
6870
const content = raw[filename]
69-
if (filename === 'description.txt') {
71+
if (filename === 'description.txt'||filename==='description.md') {
7072
continue
7173
} else if (typeof content === 'string') {
7274
files[filename] = content
@@ -93,14 +95,18 @@ function injectCreateApp(src: string): string {
9395
return src.replace(/exportdefault({[^]*\n})/, "createApp(1ドル).mount('#app')")
9496
}
9597

96-
export function resolveSFCExample(raw: ExampleData, preferComposition: boolean) {
98+
export function resolveSFCExample(
99+
raw: ExampleData,
100+
preferComposition: boolean
101+
) {
97102
const files: Record<string, string> = {}
98103
forEachComponent(
99104
raw,
100105
files,
101106
(filename, { template, composition, options, style }) => {
107+
const desc = raw['description.txt']
102108
let sfcContent =
103-
filename === 'App' ? `<!--\n${raw['description.txt']}\n-->\n\n` : ``
109+
desc&&filename === 'App' ? `<!--\n${desc}\n-->\n\n` : ``
104110
if (preferComposition) {
105111
sfcContent += `<script setup>\n${toScriptSetup(
106112
composition,
@@ -119,10 +125,14 @@ export function resolveSFCExample(raw: ExampleData, preferComposition: boolean)
119125
return files
120126
}
121127

122-
export function resolveNoBuildExample(raw: ExampleData, preferComposition: boolean) {
128+
export function resolveNoBuildExample(
129+
raw: ExampleData,
130+
preferComposition: boolean
131+
) {
123132
const files: Record<string, string> = {}
124133

125-
let html = `<!--\n${raw['description.txt']}\n-->\n\n`
134+
const desc = raw['description.txt']
135+
let html = desc ? `<!--\n${desc})}\n-->\n\n` : ``
126136
let css = ''
127137

128138
// set it first for ordering
@@ -140,7 +150,7 @@ export function resolveNoBuildExample(raw: ExampleData, preferComposition: boole
140150

141151
if (filename === 'App') {
142152
html += `<script type="module">\n${injectCreateApp(js)}<\/script>`
143-
html += `\n\n<div id="app">\n${_template}</div>`
153+
html += `\n\n<div id="app">\n${_template}\n</div>`
144154
} else {
145155
// html += `\n\n<template id="${filename}">\n${_template}</template>`
146156
js = js.replace(
@@ -158,4 +168,9 @@ export function resolveNoBuildExample(raw: ExampleData, preferComposition: boole
158168
return files
159169
}
160170

161-
171+
export function onHashChange(cb) {
172+
window.addEventListener('hashchange', cb)
173+
onBeforeUnmount(() => {
174+
window.removeEventListener('hashchange', cb)
175+
})
176+
}

0 commit comments

Comments
(0)

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /