]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
chore: add custom param parser to playground
authorEduardo San Martin Morote <posva13@gmail.com>
Tue, 18 Nov 2025 15:51:33 +0000 (16:51 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Tue, 18 Nov 2025 15:51:33 +0000 (16:51 +0100)
packages/experiments-playground/src/App.vue
packages/experiments-playground/src/pages/events.vue [new file with mode: 0644]
packages/experiments-playground/src/pages/events/(event-list).vue [new file with mode: 0644]
packages/experiments-playground/src/pages/events/[when=date].vue [new file with mode: 0644]
packages/experiments-playground/src/pages/events/[when=date]/nested.vue [new file with mode: 0644]
packages/experiments-playground/src/router/index.ts

index e4bc2db4dc6c43fb857ab2f537d746507fc3344f..5c0a53223a084e924ac66f58a98a8ca322a44d0d 100644 (file)
@@ -38,6 +38,8 @@ const queryPage = computed({
       <RouterLink to="/nested/a">Nested A</RouterLink>
       |
       <RouterLink to="/profiles">Profiles list</RouterLink>
+      |
+      <RouterLink to="/events">Events</RouterLink>
     </nav>
     <form @submit.prevent="router.push(url)">
       <label for="path">Path:</label>
diff --git a/packages/experiments-playground/src/pages/events.vue b/packages/experiments-playground/src/pages/events.vue
new file mode 100644 (file)
index 0000000..36e11ff
--- /dev/null
@@ -0,0 +1,40 @@
+<script setup lang="ts">
+import { useRoute } from 'vue-router'
+
+const route = useRoute()
+</script>
+
+<template>
+  <div>
+    <h1>Events</h1>
+
+    <ul>
+      <li>
+        <router-link to="/events" v-slot="{ href }">{{ href }}</router-link>
+      </li>
+      <li>
+        <router-link to="/events/2025" v-slot="{ href }">{{
+          href
+        }}</router-link>
+      </li>
+      <li>
+        <router-link to="/events/2025-03-24" v-slot="{ href }">{{
+          href
+        }}</router-link>
+      </li>
+      <li>
+        <router-link
+          :to="{
+            name: 'events-date-nested',
+            // @ts-expect-error: it works
+            params: { when: new Date(), ...route.params },
+          }"
+          v-slot="{ href }"
+          >{{ href }}</router-link
+        >
+      </li>
+    </ul>
+
+    <RouterView />
+  </div>
+</template>
diff --git a/packages/experiments-playground/src/pages/events/(event-list).vue b/packages/experiments-playground/src/pages/events/(event-list).vue
new file mode 100644 (file)
index 0000000..e7cf8e1
--- /dev/null
@@ -0,0 +1,3 @@
+<template>
+  <p>click on any other link</p>
+</template>
diff --git a/packages/experiments-playground/src/pages/events/[when=date].vue b/packages/experiments-playground/src/pages/events/[when=date].vue
new file mode 100644 (file)
index 0000000..b0b297e
--- /dev/null
@@ -0,0 +1,19 @@
+<script setup lang="ts">
+import { useRoute } from 'vue-router'
+
+const route = useRoute()
+</script>
+
+<template>
+  <div class="about">
+    <h2>When: {{ (route.params.when as unknown as Date).toDateString() }}</h2>
+
+    <p>
+      <code>instance of Date</code>:
+      {{ route.params.when instanceof Date }}
+      <br />
+      Time:
+      {{ (route.params.when as unknown as Date).getTime() }}
+    </p>
+  </div>
+</template>
diff --git a/packages/experiments-playground/src/pages/events/[when=date]/nested.vue b/packages/experiments-playground/src/pages/events/[when=date]/nested.vue
new file mode 100644 (file)
index 0000000..911a451
--- /dev/null
@@ -0,0 +1,3 @@
+<template>
+  <p>This is a nested page</p>
+</template>
index 4db000656367162735095fd63f1a8bb8d454a8a5..96c18c5e3ef1fecdfffe09734a40f9cd5c1fc556 100644 (file)
@@ -7,6 +7,7 @@ import {
   normalizeRouteRecord,
   PARAM_PARSER_INT,
   MatcherPatternQueryParam,
+  MatchMiss,
 } from 'vue-router/experimental'
 import type {
   EXPERIMENTAL_RouteRecordNormalized_Matchable,
@@ -26,6 +27,25 @@ const PAGE_QUERY_PATTERN_MATCHER: MatcherPatternQuery<{ page: number }> = {
   build: params => ({ page: String(params.page) }),
 }
 
+const PARAM_PARSER_DATE = {
+  get(value: string): Date {
+    const asDate = new Date(value)
+    if (Number.isNaN(asDate.getTime())) {
+      throw new MatchMiss(`Invalid date param: "${value}"`)
+    }
+
+    return asDate
+  },
+  set(value: Date): string {
+    return (
+      value
+        .toISOString()
+        // allows keeping simple dates like 2023-10-01 without time
+        .replace('T00:00:00.000Z', '')
+    )
+  },
+}
+
 const QUERY_PATTERN_MATCHER: MatcherPatternQuery<{ q?: string }> = {
   match: query => {
     return {
@@ -130,13 +150,58 @@ const r_profiles_detail = normalizeRouteRecord({
   ),
 })
 
+const r_events = normalizeRouteRecord({
+  components: { default: () => import('../pages/events.vue') },
+})
+
+const r_events_list = normalizeRouteRecord({
+  name: 'events',
+  path: new MatcherPatternPathStatic('/events'),
+  components: { default: () => import('../pages/events/(event-list).vue') },
+  parent: r_events,
+})
+
+const r_events_date = normalizeRouteRecord({
+  name: 'events-date',
+  components: { default: () => import('../pages/events/[when=date].vue') },
+  path: new MatcherPatternPathDynamic(
+    /^\/events\/([^/]+?)$/i,
+    {
+      when: [PARAM_PARSER_DATE],
+    },
+    ['events', 1]
+  ),
+  parent: r_events,
+})
+
+const r_events_nested = normalizeRouteRecord({
+  name: 'events-date-nested',
+  components: {
+    default: () => import('../pages/events/[when=date]/nested.vue'),
+  },
+  path: new MatcherPatternPathDynamic(
+    /^\/events\/([^/]+?)\/nested$/i,
+    {
+      when: [PARAM_PARSER_DATE],
+    },
+    ['events', 1, 'nested']
+  ),
+  parent: r_events_date,
+})
+
 export const router = experimental_createRouter({
   history: createWebHistory(),
   resolver: createFixedResolver<EXPERIMENTAL_RouteRecordNormalized_Matchable>([
     r_home,
     r_about,
+
+    r_events_list,
+    r_events_date,
+    r_events_nested,
+
     r_nested,
     r_nested_a,
+
     r_profiles_list,
     r_profiles_detail,
   ]),