Skip to content

Commit b74051a

Browse files
committedDec 3, 2020
fix(router-view): properly use route prop when nested
1 parent ba4b186 commit b74051a

File tree

6 files changed

+49
-12
lines changed

6 files changed

+49
-12
lines changed
 

‎__tests__/mount.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ import {
1616
import { compile } from '@vue/compiler-dom'
1717
import * as runtimeDom from '@vue/runtime-dom'
1818
import { RouteLocationNormalizedLoose } from './utils'
19-
import { routeLocationKey } from '../src/injectionSymbols'
19+
import {
20+
routeLocationKey,
21+
routerViewLocationKey,
22+
} from '../src/injectionSymbols'
2023
import { Router } from '../src'
2124

2225
export interface MountOptions {
@@ -183,6 +186,7 @@ export function createMockedRoute(initialValue: RouteLocationNormalizedLoose) {
183186
set,
184187
provides: {
185188
[routeLocationKey as symbol]: value,
189+
[routerViewLocationKey as symbol]: routeRef,
186190
},
187191
}
188192
}

‎e2e/modal/index.ts

+15-3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ const Home = defineComponent({
4747
</li>
4848
</ul>
4949
50+
<router-view />
51+
5052
<dialog ref="modal" id="dialog">
5153
<div>
5254
<div v-if="userId">
@@ -110,6 +112,10 @@ const About = defineComponent({
110112
},
111113
})
112114

115+
const Child = defineComponent({
116+
template: `<div class="child">child</div>`,
117+
})
118+
113119
const UserDetails = defineComponent({
114120
template: `<div>
115121
<h1>User #{{ id }}</h1>
@@ -121,8 +127,7 @@ const UserDetails = defineComponent({
121127
props: {
122128
id: {
123129
type: String,
124-
// FIXME: setting this to true fails with props: true, as if it didn't fit the definition of RouteComponent
125-
required: false,
130+
required: true,
126131
},
127132
},
128133
data: () => ({ users }),
@@ -132,7 +137,14 @@ const webHistory = createWebHistory('/' + __dirname)
132137
const router = createRouter({
133138
history: webHistory,
134139
routes: [
135-
{ path: '/', component: Home },
140+
{
141+
path: '/',
142+
component: Home,
143+
children: [
144+
// to check that displaying the modal doesn't change this
145+
{ path: '', component: Child },
146+
],
147+
},
136148
{ path: '/about', component: About },
137149
{ path: '/users/:id', props: true, name: 'user', component: UserDetails },
138150
],

‎e2e/specs/modal.js

+2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ module.exports = {
1414
.waitForElementPresent('#app > *', 1000)
1515
.assert.containsText('h1', 'Home')
1616
.assert.not.visible('dialog')
17+
.assert.containsText('.child', 'child')
1718

1819
.click('li:nth-child(2) button')
1920
.assert.urlEquals(baseURL + '/users/1')
2021
.assert.visible('dialog')
2122
.assert.containsText('dialog', 'User #1')
23+
.assert.containsText('.child', 'child')
2224

2325
.end()
2426
},

‎src/RouterView.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
import {
2323
matchedRouteKey,
2424
viewDepthKey,
25-
routeLocationKey,
25+
routerViewLocationKey,
2626
} from './injectionSymbols'
2727
import { assign } from './utils'
2828
import { warn } from './warning'
@@ -47,14 +47,16 @@ export const RouterViewImpl = /*#__PURE__*/ defineComponent({
4747
setup(props, { attrs, slots }) {
4848
__DEV__ && warnDeprecatedUsage()
4949

50-
const injectedRoute = inject(routeLocationKey)!
50+
const injectedRoute = inject(routerViewLocationKey)!
51+
const routeToDisplay = computed(() => props.route || injectedRoute.value)
5152
const depth = inject(viewDepthKey, 0)
5253
const matchedRouteRef = computed<RouteLocationMatched | undefined>(
53-
() => (props.route || injectedRoute).matched[depth]
54+
() => routeToDisplay.value.matched[depth]
5455
)
5556

5657
provide(viewDepthKey, depth + 1)
5758
provide(matchedRouteKey, matchedRouteRef)
59+
provide(routerViewLocationKey, routeToDisplay)
5860

5961
const viewRef = ref<ComponentPublicInstance>()
6062

@@ -93,7 +95,7 @@ export const RouterViewImpl = /*#__PURE__*/ defineComponent({
9395
)
9496

9597
return () => {
96-
const route = props.route || injectedRoute
98+
const route = routeToDisplay.value
9799
const matchedRoute = matchedRouteRef.value
98100
const ViewComponent = matchedRoute && matchedRoute.components[props.name]
99101
// we need the value at the time we render because when we unmount, we

‎src/injectionSymbols.ts

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { InjectionKey, ComputedRef } from 'vue'
1+
import { InjectionKey, ComputedRef, Ref } from 'vue'
22
import { RouteLocationNormalizedLoaded } from './types'
33
import { Router } from './router'
44
import { RouteRecordNormalized } from './matcher/types'
@@ -35,7 +35,8 @@ export const viewDepthKey = /*#__PURE__*/ PolySymbol(
3535
) as InjectionKey<number>
3636

3737
/**
38-
* Allows overriding the router instance returned by `useRouter` in tests. r stands for router
38+
* Allows overriding the router instance returned by `useRouter` in tests. r
39+
* stands for router
3940
*
4041
* @internal
4142
*/
@@ -44,10 +45,21 @@ export const routerKey = /*#__PURE__*/ PolySymbol(
4445
) as InjectionKey<Router>
4546

4647
/**
47-
* Allows overriding the current route returned by `useRoute` in tests. rl stands for route location
48+
* Allows overriding the current route returned by `useRoute` in tests. rl
49+
* stands for route location
4850
*
4951
* @internal
5052
*/
5153
export const routeLocationKey = /*#__PURE__*/ PolySymbol(
5254
__DEV__ ? 'route location' : 'rl'
5355
) as InjectionKey<RouteLocationNormalizedLoaded>
56+
57+
/**
58+
* Allows overriding the current route used by router-view. Internally this is
59+
* used when the `route` prop is passed.
60+
*
61+
* @internal
62+
*/
63+
export const routerViewLocationKey = /*#__PURE__*/ PolySymbol(
64+
__DEV__ ? 'router view location' : 'rvl'
65+
) as InjectionKey<Ref<RouteLocationNormalizedLoaded>>

‎src/router.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ import { extractComponentsGuards, guardToPromiseFn } from './navigationGuards'
5656
import { warn } from './warning'
5757
import { RouterLink } from './RouterLink'
5858
import { RouterView } from './RouterView'
59-
import { routerKey, routeLocationKey } from './injectionSymbols'
59+
import {
60+
routeLocationKey,
61+
routerKey,
62+
routerViewLocationKey,
63+
} from './injectionSymbols'
6064
import { addDevtools } from './devtools'
6165

6266
/**
@@ -1098,6 +1102,7 @@ export function createRouter(options: RouterOptions): Router {
10981102

10991103
app.provide(routerKey, router)
11001104
app.provide(routeLocationKey, reactive(reactiveRoute))
1105+
app.provide(routerViewLocationKey, currentRoute)
11011106

11021107
let unmountApp = app.unmount
11031108
installedApps.add(app)

0 commit comments

Comments
 (0)