]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
fix(link): navigate to the alias path
authorEduardo San Martin Morote <posva13@gmail.com>
Thu, 12 Mar 2020 14:49:28 +0000 (15:49 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Thu, 12 Mar 2020 16:25:36 +0000 (17:25 +0100)
__tests__/matcher/resolve.spec.ts
src/matcher/index.ts
src/router.ts

index 01ca72e2e806ca04bd8e9d36bbc55ff577bda1cf..70be36142c72f909d7439c01437e44fb0de46c3f 100644 (file)
@@ -156,7 +156,7 @@ describe('Router Matcher', () => {
         )
       })
 
-      it('resolves an alias with children', () => {
+      it('resolves an alias with children to the alias when using the path', () => {
         const children = [{ path: 'one', component, name: 'nested' }]
         assertRecordMatch(
           {
@@ -182,6 +182,33 @@ describe('Router Matcher', () => {
           }
         )
       })
+
+      it('resolves the original path of the named children of a route with an alias', () => {
+        const children = [{ path: 'one', component, name: 'nested' }]
+        assertRecordMatch(
+          {
+            path: '/parent',
+            alias: '/p',
+            component,
+            children,
+          },
+          { name: 'nested' },
+          {
+            path: '/parent/one',
+            name: 'nested',
+            params: {},
+            matched: [
+              {
+                path: '/parent',
+                children,
+                components,
+                aliasOf: undefined,
+              },
+              { path: '/parent/one', name: 'nested', components },
+            ],
+          }
+        )
+      })
     })
 
     describe('LocationAsPath', () => {
index 7ccf9d9a33270ad5893f11634f6a786cdfc1949b..97802d99e2653fbe504fe2e1232abc9964a9824b 100644 (file)
@@ -132,7 +132,7 @@ export function createRouterMatcher(
     // while (i < matchers.length && matcher.score <= matchers[i].score) i++
     matchers.splice(i, 0, matcher)
     // only add the original record to the name map
-    if (matcher.record.name && !matcher.record.aliasOf)
+    if (matcher.record.name && !isAliasRecord(matcher))
       matcherMap.set(matcher.record.name, matcher)
   }
 
@@ -245,4 +245,17 @@ export function normalizeRouteRecord(
   }
 }
 
+/**
+ * Checks if a record or any of its parent is an alias
+ * @param record
+ */
+function isAliasRecord(record: RouteRecordMatcher | undefined): boolean {
+  while (record) {
+    if (record.record.aliasOf) return true
+    record = record.parent
+  }
+
+  return false
+}
+
 export { PathParserOptions }
index 54fd5da3adeb9f5a71d4cb020afedf05c1ac628c..ae9f18aef0478bc8694d81174eeaa2a880111954 100644 (file)
@@ -184,15 +184,19 @@ export function createRouter({
     }
   }
 
-  function push(to: RouteLocation): Promise<RouteLocationNormalized> {
+  function push(
+    to: RouteLocation | RouteLocationNormalized
+  ): Promise<RouteLocationNormalized> {
     return pushWithRedirect(to, undefined)
   }
 
   async function pushWithRedirect(
-    to: RouteLocation,
+    to: RouteLocation | RouteLocationNormalized,
     redirectedFrom: RouteLocationNormalized | undefined
   ): Promise<RouteLocationNormalized> {
-    const toLocation: RouteLocationNormalized = (pendingLocation = resolve(to))
+    const toLocation: RouteLocationNormalized = (pendingLocation =
+      // Some functions will pass a normalized location and we don't need to resolve it again
+      typeof to === 'object' && 'matched' in to ? to : resolve(to))
     const from: RouteLocationNormalized = currentRoute.value
     // @ts-ignore: no need to check the string as force do not exist on a string
     const force: boolean | undefined = to.force
@@ -222,12 +226,18 @@ export function createRouter({
       triggerError(error)
     }
 
-    finalizeNavigation(toLocation, from, true, to.replace === true)
+    finalizeNavigation(
+      toLocation,
+      from,
+      true,
+      // RouteLocationNormalized will give undefined
+      (to as RouteLocation).replace === true
+    )
 
     return currentRoute.value
   }
 
-  function replace(to: RouteLocation) {
+  function replace(to: RouteLocation | RouteLocationNormalized) {
     const location = typeof to === 'string' ? { path: to } : to
     return push({ ...location, replace: true })
   }