-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Internal: Refactor Vue playground (#1864)
* Add dynamic routes to Vue playground * Simplify * Upgrade to Vite 3.0 * Use TypeScript
- Loading branch information
1 parent
dd2feef
commit b267ce3
Showing
10 changed files
with
322 additions
and
300 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,42 @@ | ||
<script setup> | ||
import { defineComponent } from 'vue' | ||
import { useRouter } from 'vue-router' | ||
let Examples = defineComponent({ | ||
props: ['routes'], | ||
setup: | ||
(props, { slots }) => | ||
() => | ||
slots.default({ routes: props.routes, slots }), | ||
}) | ||
let router = useRouter() | ||
let routes = router | ||
.getRoutes() | ||
.filter((example) => example.path !== '/') | ||
.filter((route) => route.meta.isRoot) | ||
</script> | ||
|
||
<template> | ||
<div class="container mx-auto my-24"> | ||
<div class="prose"> | ||
<h2>Examples</h2> | ||
<Examples :examples="examples" /> | ||
<Examples :routes="routes" v-slot="{ routes, slots }"> | ||
<ul> | ||
<li v-for="{ children, meta, path } in routes"> | ||
<template v-if="children.length > 0"> | ||
<h3 class="text-xl">{{ meta.name }}</h3> | ||
<!-- This is a bit cursed but it works --> | ||
<component v-for="vnode in slots.default({ routes: children, slots })" :is="vnode" /> | ||
</template> | ||
<template v-else> | ||
<router-link :key="path" :to="path"> | ||
{{ meta.name }} | ||
</router-link> | ||
</template> | ||
</li> | ||
</ul> | ||
</Examples> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
import { defineComponent, h } from 'vue' | ||
import { RouterLink } from 'vue-router' | ||
import routes from '../routes.json' | ||
let Examples = defineComponent({ | ||
props: ['examples'], | ||
setup(props) { | ||
return () => { | ||
return h( | ||
'ul', | ||
props.examples | ||
.filter((example) => example.path !== '/') | ||
.map((example) => | ||
h( | ||
'li', | ||
{ key: example.path }, | ||
example.children | ||
? h('h3', { class: 'text-xl' }, example.name) | ||
: [h(RouterLink, { to: example.path }, () => example.name)], | ||
example.children && h(Examples, { examples: example.children }) | ||
) | ||
) | ||
) | ||
} | ||
}, | ||
}) | ||
export default { | ||
components: { Examples }, | ||
setup() { | ||
return { | ||
examples: routes, | ||
} | ||
}, | ||
} | ||
</script> |
File renamed without changes.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { createWebHistory, createRouter, RouterView } from 'vue-router' | ||
|
||
type Component = import('vue').Component | ||
|
||
function buildRoutes() { | ||
function titleCase(str) { | ||
return str | ||
.toLocaleLowerCase() | ||
.split('-') | ||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1)) | ||
.join(' ') | ||
} | ||
|
||
// 1. Get all the components in the src/components directory | ||
let files = Object.entries( | ||
import.meta.glob('./components/**/*.vue', { | ||
eager: true, | ||
import: 'default', | ||
}) | ||
) as [string, Component][] | ||
|
||
// 2.a. Swap the file names for route urls | ||
// 2.b. Resolve the default import for each component | ||
files = files.map(([file, component]) => [ | ||
file | ||
.replace('./components/', '/') | ||
.replace(/\.vue$/, '') | ||
.toLocaleLowerCase() | ||
.replace(/^\/home$/g, '/'), | ||
component, | ||
]) | ||
|
||
let alreadyAdded = new Set() | ||
|
||
// 3. Add a route for each directory (if not already added) | ||
files = files.flatMap((entry) => { | ||
let dirs = entry[0].split('/').slice(1, -1) | ||
|
||
let paths: [string, Component][] = [] | ||
|
||
for (const [idx] of dirs.entries()) { | ||
let path = `/` + dirs.slice(0, idx + 1).join('/') | ||
if (alreadyAdded.has(path)) { | ||
continue | ||
} | ||
|
||
paths.push([path, RouterView]) | ||
alreadyAdded.add(path) | ||
} | ||
|
||
return [...paths, entry] | ||
}) | ||
|
||
// 4. Sort the routes alphabetically and by length | ||
files.sort((a, b) => a[0].localeCompare(b[0])) | ||
|
||
// 5. Create the nested routes | ||
let routes = [] | ||
let routesByPath = {} | ||
|
||
for (let [path, component] of files) { | ||
let prefix = path.split('/').slice(0, -1).join('/') | ||
let parent = routesByPath[prefix]?.children ?? routes | ||
let route = { | ||
path, | ||
component: component, | ||
children: [], | ||
meta: { | ||
name: titleCase(path.match(/[^/]+$/)?.[0] ?? 'Home'), | ||
isRoot: parent === routes, | ||
}, | ||
} | ||
|
||
parent.push((routesByPath[path] = route)) | ||
} | ||
|
||
return routes | ||
} | ||
|
||
export default createRouter({ | ||
history: createWebHistory(), | ||
routes: buildRoutes(), | ||
}) |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.