]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
feat: pass state in guards and redirect
authorEduardo San Martin Morote <posva13@gmail.com>
Tue, 16 Aug 2022 15:11:55 +0000 (17:11 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Tue, 16 Aug 2022 15:11:55 +0000 (17:11 +0200)
Close #1472

packages/router/__tests__/guards/beforeEach.spec.ts
packages/router/src/router.ts

index 4cc45e0894712b649503095535c40d10470b5cc8..ddc15ef073e109633b329deeac700a56b892dbec 100644 (file)
@@ -19,6 +19,10 @@ const routes: RouteRecordRaw[] = [
       { path: 'home', name: 'nested-home', component: Home },
     ],
   },
+  {
+    path: '/redirect',
+    redirect: { path: '/other', state: { fromRecord: true } },
+  },
 ]
 
 describe('router.beforeEach', () => {
@@ -106,6 +110,50 @@ describe('router.beforeEach', () => {
     expect(router.currentRoute.value.fullPath).toBe('/other')
   })
 
+  it('can add state when redirecting', async () => {
+    const router = createRouter({ routes })
+    await router.push('/foo')
+    router.beforeEach((to, from) => {
+      // only allow going to /other
+      if (to.fullPath !== '/other') {
+        return {
+          path: '/other',
+          state: { added: 'state' },
+        }
+      }
+      return
+    })
+
+    const spy = jest.spyOn(history, 'pushState')
+    await router.push({ path: '/', state: { a: 'a' } })
+    expect(spy).toHaveBeenCalledTimes(1)
+    // called before redirect
+    expect(spy).toHaveBeenNthCalledWith(
+      1,
+      expect.objectContaining({ added: 'state', a: 'a' }),
+      '',
+      expect.stringMatching(/\/other$/)
+    )
+    spy.mockClear()
+  })
+
+  it('can add state to a redirect route', async () => {
+    const router = createRouter({ routes })
+    await router.push('/foo')
+
+    const spy = jest.spyOn(history, 'pushState')
+    await router.push({ path: '/redirect', state: { a: 'a' } })
+    expect(spy).toHaveBeenCalledTimes(1)
+    // called before redirect
+    expect(spy).toHaveBeenNthCalledWith(
+      1,
+      expect.objectContaining({ fromRecord: true, a: 'a' }),
+      '',
+      expect.stringMatching(/\/other$/)
+    )
+    spy.mockClear()
+  })
+
   async function assertRedirect(redirectFn: (i: string) => RouteLocationRaw) {
     const spy = jest.fn()
     const router = createRouter({ routes })
index e2d392cd9e141727a55f09d806155c405e570f2f..40bf050b7ec4f652bfd63601cb75643e2d0358ea 100644 (file)
@@ -655,7 +655,10 @@ export function createRouter(options: RouterOptions): Router {
     if (shouldRedirect)
       return pushWithRedirect(
         assign(locationAsObject(shouldRedirect), {
-          state: data,
+          state:
+            typeof shouldRedirect === 'object'
+              ? assign({}, data, shouldRedirect.state)
+              : data,
           force,
           replace,
         }),
@@ -735,7 +738,10 @@ export function createRouter(options: RouterOptions): Router {
                 },
                 locationAsObject(failure.to),
                 {
-                  state: data,
+                  state:
+                    typeof failure.to === 'object'
+                      ? assign({}, data, failure.to.state)
+                      : data,
                   force,
                 }
               ),