Skip to content

Commit

Permalink
fix(guards): correctly reuse guards (#616)
Browse files Browse the repository at this point in the history
Fix #614
  • Loading branch information
posva committed Nov 24, 2020
1 parent 6448a14 commit 95d44c8
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 26 deletions.
12 changes: 6 additions & 6 deletions __tests__/matcher/records.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ describe('normalizeRouteRecord', () => {
children: [],
aliasOf: undefined,
components: { default: {} },
leaveGuards: [],
updateGuards: [],
leaveGuards: expect.any(Set),
updateGuards: expect.any(Set),
instances: {},
meta: {},
name: undefined,
Expand All @@ -35,8 +35,8 @@ describe('normalizeRouteRecord', () => {
beforeEnter,
children: [{ path: '/child' }],
components: { default: {} },
leaveGuards: [],
updateGuards: [],
leaveGuards: expect.any(Set),
updateGuards: expect.any(Set),
instances: {},
meta: { foo: true },
name: 'name',
Expand Down Expand Up @@ -77,8 +77,8 @@ describe('normalizeRouteRecord', () => {
beforeEnter,
children: [{ path: '/child' }],
components: { one: {} },
leaveGuards: [],
updateGuards: [],
leaveGuards: expect.any(Set),
updateGuards: expect.any(Set),
instances: {},
meta: { foo: true },
name: 'name',
Expand Down
8 changes: 6 additions & 2 deletions e2e/guards-instances/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const state = reactive({
*/
function createTestComponent(key: string) {
return defineComponent({
name: key,
template: `
<div :id="key">
{{ key }}
Expand Down Expand Up @@ -196,12 +197,12 @@ leaves: {{ state.leave }}
</router-view>
</template>
<template v-else-if="testCase === 'keyed'">
<router-view :key="$route.query.foo" class="view" />
<router-view :key="$route.query.foo || undefined" class="view" />
</template>
<template v-else-if="testCase === 'keepalivekeyed'">
<router-view v-slot="{ Component }" >
<keep-alive>
<component :is="Component" :key="$route.query.foo" class="view" />
<component :is="Component" :key="$route.query.foo || undefined" class="view" />
</keep-alive>
</router-view>
</template>
Expand Down Expand Up @@ -232,4 +233,7 @@ leaves: {{ state.leave }}

app.use(router)

// @ts-ignore
window.r = router

app.mount('#app')
2 changes: 1 addition & 1 deletion e2e/specs/guards-instances.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ module.exports = {
.expect.element('#logs')
.text.to.equal(
[
// lol
// to force new lines formatting
`${name}: update /f/2 - /f/2`,
`${name}: setup:update /f/2 - /f/2`,
].join('\n')
Expand Down
2 changes: 1 addition & 1 deletion src/RouterView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const RouterViewImpl = /*#__PURE__*/ defineComponent({
to.instances[name] = instance
// the component instance is reused for a different route or name so
// we copy any saved update or leave guards
if (from && instance === oldInstance) {
if (from && from !== to && instance && instance === oldInstance) {
to.leaveGuards = from.leaveGuards
to.updateGuards = from.updateGuards
}
Expand Down
4 changes: 2 additions & 2 deletions src/matcher/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,8 @@ export function normalizeRouteRecord(
props: normalizeRecordProps(record),
children: record.children || [],
instances: {},
leaveGuards: [],
updateGuards: [],
leaveGuards: new Set(),
updateGuards: new Set(),
enterCallbacks: {},
components:
'components' in record
Expand Down
4 changes: 2 additions & 2 deletions src/matcher/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ export interface RouteRecordNormalized {
*
* @internal
*/
leaveGuards: NavigationGuard[]
leaveGuards: Set<NavigationGuard>
/**
* Registered update guards
*
* @internal
*/
updateGuards: NavigationGuard[]
updateGuards: Set<NavigationGuard>
/**
* Registered beforeRouteEnter callbacks passed to `next` or returned in guards
*
Expand Down
18 changes: 10 additions & 8 deletions src/navigationGuards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,23 @@ import { RouteRecordNormalized } from './matcher/types'
import { isESModule } from './utils'
import { warn } from './warning'

function registerGuard(list: NavigationGuard[], guard: NavigationGuard) {
function registerGuard(
record: RouteRecordNormalized,
name: 'leaveGuards' | 'updateGuards',
guard: NavigationGuard
) {
const removeFromList = () => {
const index = list.indexOf(guard)
if (index > -1) list.splice(index, 1)
record[name].delete(guard)
}

onUnmounted(removeFromList)
onDeactivated(removeFromList)

onActivated(() => {
const index = list.indexOf(guard)
if (index < 0) list.push(guard)
record[name].add(guard)
})

list.push(guard)
record[name].add(guard)
}

/**
Expand All @@ -65,7 +67,7 @@ export function onBeforeRouteLeave(leaveGuard: NavigationGuard) {
return
}

registerGuard(activeRecord.leaveGuards, leaveGuard)
registerGuard(activeRecord, 'leaveGuards', leaveGuard)
}

/**
Expand All @@ -92,7 +94,7 @@ export function onBeforeRouteUpdate(updateGuard: NavigationGuard) {
return
}

registerGuard(activeRecord.updateGuards, updateGuard)
registerGuard(activeRecord, 'updateGuards', updateGuard)
}

export function guardToPromiseFn(
Expand Down
8 changes: 4 additions & 4 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -728,9 +728,9 @@ export function createRouter(options: RouterOptions): Router {

// leavingRecords is already reversed
for (const record of leavingRecords) {
for (const guard of record.leaveGuards) {
record.leaveGuards.forEach(guard => {
guards.push(guardToPromiseFn(guard, to, from))
}
})
}

const canceledNavigationCheck = checkCanceledNavigationAndReject.bind(
Expand Down Expand Up @@ -764,9 +764,9 @@ export function createRouter(options: RouterOptions): Router {
)

for (const record of updatingRecords) {
for (const guard of record.updateGuards) {
record.updateGuards.forEach(guard => {
guards.push(guardToPromiseFn(guard, to, from))
}
})
}
guards.push(canceledNavigationCheck)

Expand Down

0 comments on commit 95d44c8

Please sign in to comment.