Skip to content

Commit

Permalink
feat: add basic data loaders
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Jul 21, 2022
1 parent 3c3c5d8 commit 9c19fd2
Show file tree
Hide file tree
Showing 21 changed files with 278 additions and 70 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"fast-glob": "^3.2.11",
"json5": "^2.2.1",
"local-pkg": "^0.4.2",
"mlly": "^0.5.4",
"pathe": "^0.3.2",
"scule": "^0.2.1",
"unplugin": "^0.7.2",
Expand Down
2 changes: 1 addition & 1 deletion playground/auto-imports.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Generated by 'unplugin-auto-import'
export {}
declare global {
const defineLoader: typeof import('unplugin-vue-router/runtime')['_defineLoader']
const defineLoader: typeof import('@vue-router')['defineLoader']
const useRoute: typeof import('@vue-router')['useRoute']
const useRouter: typeof import('@vue-router')['useRouter']
}
55 changes: 46 additions & 9 deletions playground/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,32 @@ const customRoute = useRoute('/deep/nesting/works/custom-path')
<header>
<div class="wrapper">
<nav>
<RouterLink to="/users/2">About</RouterLink>
<RouterLink :to="{ name: '/articles/[id]', params: { id: 2 } }"
>About</RouterLink
>
<RouterLink :to="{ path: '/articles', query: { test: 'query', n: 2 } }"
>About</RouterLink
>
<ul>
<li>
<RouterLink to="/">Home</RouterLink>
</li>
<li>
<RouterLink to="/Eduardo">[name]</RouterLink>
</li>
<li>
<RouterLink to="/about">About</RouterLink>
</li>
<li>
<RouterLink :to="{ name: '/articles/[id]', params: { id: 2 } }"
>Some Article</RouterLink
>
</li>
<li>
<RouterLink
:to="{ path: '/articles', query: { test: 'query', n: 2 } }"
>Articles with query</RouterLink
>
</li>
</ul>

<button @click="$router.push('/oeu')">Click</button>
{{ $route.name === '' }}
<RouterLink to="/:name" v-slot="{ route }">
<RouterLink to="/named-route" v-slot="{ route }">
:name param is:
{{ (route as RouteLocationNormalizedLoaded<'/[name]'>).params.name }}
</RouterLink>
</nav>
Expand All @@ -58,3 +74,24 @@ const customRoute = useRoute('/deep/nesting/works/custom-path')
<hr />
<RouterView name="named" />
</template>

<style scoped>
ul {
padding-left: 0;
}
ul > li {
display: inline-block;
}
ul > li:not(:first-child) {
margin-left: 0.5rem;
}
li > a {
text-decoration: none;
}
.router-link-active {
text-decoration: underline;
font-weight: bold;
}
</style>
2 changes: 0 additions & 2 deletions playground/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ const router = createRouter({
history: createWebHistory(),
})

console.log(router)

const app = createApp(App)

app.use(router)
Expand Down
41 changes: 31 additions & 10 deletions playground/src/routes/[name].vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
<script lang="ts">
export const useUserData = defineLoader(async (route) => {
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
export const useUserData = defineLoader('/[name]', async (route) => {
await delay(1000)
if (route.name === '/[name]') {
route.params
}
const user = {
name: 'Edu',
name: route.params.name || 'Edu',
id: route.params.id || 24,
when: new Date().toUTCString(),
}
return { user }
})
Expand All @@ -11,7 +18,14 @@ export default {}
const other = 'hello'
export const useOne = defineLoader(async () => ({ one: 'one' }))
export const useOne = defineLoader(async (route) => {
if (route.name === '/[name]') {
route.params.name
route.params.id
}
return { one: 'one' }
})
export const useTwo = defineLoader(async () => ({ two: 'two' }))
// export { useOne, useTwo, other }
Expand All @@ -21,8 +35,12 @@ export const useTwo = defineLoader(async () => ({ two: 'two' }))
import { onBeforeRouteLeave, onBeforeRouteUpdate } from '@vue-router'
import type { RouterTyped, RouteRecordRaw } from '@vue-router'
const thing = 'THING'
// const $route = useRoute()
const { user, pending, refresh } = useUserData()
const router = useRouter()
if (router.currentRoute.value.name === '/[name]') {
router.currentRoute.value.params.name
Expand Down Expand Up @@ -86,18 +104,21 @@ defineRoute((route) => ({
],
}))
defineRouteMeta<{ transition: string }>()
defineRouteMeta({
transition: 'fade' as 'fade' | 'slide',
})
defineRouteMeta<{ transition: 'fade' | 'slide' }>({
transition: 'fade',
})
// defineRouteMeta<{ transition: string }>()
// defineRouteMeta({
// transition: 'fade' as 'fade' | 'slide',
// })
// defineRouteMeta<{ transition: 'fade' | 'slide' }>({
// transition: 'fade',
// })
</script>

<template>
<main>
<h1>Param: {{ $route.name === '/[name]' && $route.params.name }}</h1>
<h2>Param: {{ route.params.name }}</h2>
<p v-show="false">{{ thing }}</p>
<p v-if="pending">Loading user...</p>
<pre v-else>{{ user }}</pre>
</main>
</template>
3 changes: 2 additions & 1 deletion playground/src/routes/custom-name-and-path.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
{
"$schema": "https://raw.githubusercontent.com/posva/unplugin-vue-router/main/route.schema.json",
"name": "the most rebel",
"path": "/most-rebel"
"path": "/most-rebel",
"props": true
}
</route>

Expand Down
16 changes: 16 additions & 0 deletions playground/typed-router.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import type {
RouterLinkTyped,
NavigationGuard,
UseLinkFnTyped,

// data fetching
DataLoader,
} from 'unplugin-vue-router'

declare module '@vue-router/routes' {
Expand Down Expand Up @@ -103,6 +106,19 @@ declare module '@vue-router' {

export function onBeforeRouteLeave(guard: NavigationGuard<RouteNamedMap>): void
export function onBeforeRouteUpdate(guard: NavigationGuard<RouteNamedMap>): void

export function defineLoader<
P extends Promise<any>,
Name extends keyof RouteNamedMap = keyof RouteNamedMap
>(
name: Name,
loader: (route: RouteLocationNormalizedLoaded<Name>) => P
): DataLoader<Awaited<P>>
export function defineLoader<
P extends Promise<any>
>(
loader: (route: RouteLocationNormalizedLoaded) => P
): DataLoader<Awaited<P>>
}

declare module 'vue-router' {
Expand Down
2 changes: 1 addition & 1 deletion playground/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default defineConfig({
imports: [
{
'@vue-router': VueRouterExports,
'unplugin-vue-router/runtime': RuntimeExports,
// 'unplugin-vue-router/runtime': RuntimeExports,
},
],
}),
Expand Down
5 changes: 2 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions src/codegen/generateDTS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import type {
RouterLinkTyped,
NavigationGuard,
UseLinkFnTyped,
// data fetching
DataLoader,
} from 'unplugin-vue-router'
declare module '${routesModule}' {
Expand Down Expand Up @@ -83,6 +86,19 @@ declare module '${vueRouterModule}' {
export function onBeforeRouteLeave(guard: NavigationGuard<RouteNamedMap>): void
export function onBeforeRouteUpdate(guard: NavigationGuard<RouteNamedMap>): void
export function defineLoader<
P extends Promise<any>,
Name extends keyof RouteNamedMap = keyof RouteNamedMap
>(
name: Name,
loader: (route: RouteLocationNormalizedLoaded<Name>) => P
): DataLoader<Awaited<P>>
export function defineLoader<
P extends Promise<any>
>(
loader: (route: RouteLocationNormalizedLoaded) => P
): DataLoader<Awaited<P>>
}
declare module 'vue-router' {
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/generateRouteRecords.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ describe('generateRouteRecord', () => {
it('adds meta data', () => {
const tree = createPrefixTree(DEFAULT_OPTIONS)
const node = tree.insert('index.vue')
node.mergeCustomRouteBlock({
node.setCustomRouteBlock({
meta: {
auth: true,
title: 'Home',
Expand Down
26 changes: 23 additions & 3 deletions src/codegen/generateRouteRecords.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ ${node
.join(',\n')}
${indentStr}],`
: '/* no children */'
}${formatMeta(node.meta, indentStr)}
}${formatMeta(node, indentStr)}
${startIndent}}`
}

Expand All @@ -56,12 +56,32 @@ ${files
${indentStr}},`
}

function formatMeta(meta: string, indent: string): string {
function generateImportList(node: TreeLeaf, indentStr: string) {
const files = Array.from(node.value.filePaths)

return `[
${files
.map(([_key, path]) => `${indentStr} () => import('${path}')`)
.join(',\n')}
${indentStr}]`
}

const LOADER_GUARD_RE = /['"]_loaderGuard['"]:.*$/

function formatMeta(node: TreeLeaf, indent: string): string {
const meta = node.meta
const formatted =
meta &&
meta
.split('\n')
.map((line) => indent + line)
.map(
(line) =>
indent +
line.replace(
LOADER_GUARD_RE,
'[_LoaderSymbol]: ' + generateImportList(node, indent + ' ') + ','
)
)
.join('\n')

return formatted ? '\n' + indent + 'meta: ' + formatted.trimStart() : ''
Expand Down
29 changes: 29 additions & 0 deletions src/codegen/vueRouterModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// NOTE: this code needs to be generated because otherwise it doesn't go through transforms and `@vue-router/routes`
// cannot be resolved.
export function generateVueRouterProxy(routesModule: string) {
return `
import { routes } from '${routesModule}'
import { createRouter as _createRouter } from 'vue-router'
import {
_setupDataFetchingGuard,
} from 'unplugin-vue-router/runtime'
export * from 'vue-router'
export {
_defineLoader as defineLoader,
} from 'unplugin-vue-router/runtime'
export function createRouter(options) {
const { extendRoutes } = options
// use Object.assign for better browser support
const router = _createRouter(Object.assign(
options,
{ routes: typeof extendRoutes === 'function' ? extendRoutes(routes) : routes },
))
_setupDataFetchingGuard(router)
return router
}
`
}
Loading

0 comments on commit 9c19fd2

Please sign in to comment.