Skip to content

Commit

Permalink
feat: merge meta fields
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Apr 14, 2020
1 parent 760d216 commit 72a052f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
18 changes: 18 additions & 0 deletions __tests__/router.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ const routes: RouteRecordRaw[] = [
{ path: '/repeat/:r+', name: 'repeat', component: components.Bar },
{ path: '/to-p/:p', redirect: to => `/p/${to.params.p}` },
{ path: '/before-leave', component: components.BeforeLeave },
{
path: '/parent',
meta: { fromParent: 'foo' },
component: components.Foo,
children: [
{ path: 'child', meta: { fromChild: 'bar' }, component: components.Foo },
],
},
{
path: '/inc-query-hash',
redirect: to => ({
Expand Down Expand Up @@ -125,6 +133,16 @@ describe('Router', () => {
expect(stringifyQuery).toHaveBeenCalledWith({ foo: 'bar' })
})

it('merges meta properties from parent to child', async () => {
const { router } = await newRouter()
expect(router.resolve('/parent')).toMatchObject({
meta: { fromParent: 'foo' },
})
expect(router.resolve('/parent/child')).toMatchObject({
meta: { fromParent: 'foo', fromChild: 'bar' },
})
})

it('can do initial navigation to /', async () => {
const router = createRouter({
history: createMemoryHistory(),
Expand Down
17 changes: 16 additions & 1 deletion src/matcher/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ export function createRouterMatcher(
path,
params,
matched,
meta: matcher ? matcher.record.meta : {},
meta: mergeMetaFields(matched),
}
}

Expand Down Expand Up @@ -306,4 +306,19 @@ function isAliasRecord(record: RouteRecordMatcher | undefined): boolean {
return false
}

/**
* Merge meta fields of an array of records
*
* @param matched array of matched records
*/
function mergeMetaFields(matched: MatcherLocation['matched']) {
return matched.reduce(
(meta, record) => ({
...meta,
...record.meta,
}),
{} as MatcherLocation['meta']
)
}

export { PathParserOptions }

4 comments on commit 72a052f

@ByScripts
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello,

I'm migrating a Vue 2 app to Vue 3 ans this completely broke the app.

If I understand correctly, there is no way to define a meta only for a route (and not its children) ?

For example, I'm using the meta field to know if a route should be authenticated or not, and this break the whole app since the root page is public (and propagate "public: true" to all children).

Another example: I was also using { ignore: true } that, when present, prevented to go to the route (with next(false) in guard), and this also broken all children routes.

Could we imagine a way to not propagate some meta ?

{
  path: '/',
  meta: { public: true, otherMeta: 'foobar' },
  preventMetaPropagation: ['public'] // This would prevent "public" to be propagated but not "otherMeta"
}

Thank you.

@posva
Copy link
Member Author

@posva posva commented on 72a052f Oct 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can still go through matched[x].meta to check any specific meta field.
Another solution is overriding the meta property in children declaration:

{
  path: '/',
  meta: { auth: true },
  children: [{ path: 'stuff', meta: { auth: false }}]
}

@ByScripts
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having to pass all metas to all children is really annoying. That means we are no longer able to have a default value for meta (const foo = to.meta.foo || 'My value')

I'm also using meta for optional page title, "reload profile" flag for some page and so on...

Thanks for the matched trick, I'll stick to this for now, but it feel a little hacky.

I searched the tickets, I'm surprised I seem to be the only one who doesn't want to propagate the meta ^^

Again, thank you.

@posva
Copy link
Member Author

@posva posva commented on 72a052f Oct 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I searched the tickets, I'm surprised I seem to be the only one who doesn't want to propagate the meta ^^

Yeah, most people prefer to merge meta rather than going through the matched array. It's not hacky, it's fine to use.

Please sign in to comment.