Skip to content

Commit f3fed80

Browse files
authored
Merge meta fields from parent to child in RouteLocation (#144)
* initial version * fix sample * rename
1 parent a4e0db1 commit f3fed80

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
- Start Date: 2020-03-12
2+
- Target Major Version: Router 4.x
3+
- Reference Issues: N/A
4+
- Implementation PR:
5+
6+
# Summary
7+
8+
When creating routes, you can attach arbitrary data with the `meta` property:
9+
10+
```js
11+
{ path: '/profile', meta: { requiresAuth: true }}
12+
```
13+
14+
It's then accessible in navigation guards and on `$route`:
15+
16+
```js
17+
router.beforeEach((to, from, next) => {
18+
if (to.meta.requiresAuth && !auth.loggedIn()) next('/login')
19+
else next()
20+
})
21+
```
22+
23+
However, when dealing with nested routes, `meta` will contain only the matched route `meta`. You can still go through the array of `matched` records like [pointed out in the documentation](https://router.vuejs.org/guide/advanced/meta.html#route-meta-fields):
24+
25+
```js
26+
router.beforeEach((to, from, next) => {
27+
if (to.matched.some(record => record.meta.requiresAuth))
28+
// ...
29+
})
30+
```
31+
32+
My proposal is to merge all matched routes meta, from parent to child so we can do `to.matched.requiresAuth`. I believe this is what Nuxt does but I couldn't find a link in the docs.
33+
34+
# Basic example
35+
36+
Given a nested route:
37+
38+
```js
39+
{
40+
path: '/parent',
41+
meta: { requiresAuth: true, isChild: false },
42+
children: [
43+
{ path: 'child', meta: { isChild: true }}
44+
]
45+
}
46+
```
47+
48+
Navigating to `/parent/child` should generate a route with the following `meta` property:
49+
50+
```js
51+
{ requiresAuth: true, isChild: true }
52+
```
53+
54+
# Motivation
55+
56+
Most of the time, merging the `meta` property is what we need. I've never seen a case where I exclusively needed the most nested route `meta` property.
57+
58+
This would remove the need of doing `to.matched.some` to check if a `meta` field is present. Instead, it will be only necessary to use it to check overriden `meta` properties.
59+
60+
# Detailed design
61+
62+
The `meta` property is merged only at the first level, like `Object.assign` and the _spread operator_:
63+
64+
```js
65+
{
66+
path: '/parent',
67+
meta: { nested: { a: true } },
68+
children: [
69+
{ path: 'child', meta: { nested: { b: true }}}
70+
]
71+
}
72+
```
73+
74+
yields the following `meta` object when at `/parent/child`:
75+
76+
```js
77+
{
78+
nested: {
79+
b: true
80+
}
81+
}
82+
```
83+
84+
# Drawbacks
85+
86+
- This is technically a breaking change

0 commit comments

Comments
 (0)