]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
fix(router-view): properly use route prop when nested
authorEduardo San Martin Morote <posva13@gmail.com>
Thu, 3 Dec 2020 09:49:41 +0000 (10:49 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Thu, 3 Dec 2020 09:59:12 +0000 (10:59 +0100)
__tests__/mount.ts
e2e/modal/index.ts
e2e/specs/modal.js
src/RouterView.ts
src/injectionSymbols.ts
src/router.ts

index c83567c82bef2e7da7be6cefe1edf88d9c9eebd9..41976e4332cc2b9e05516fcc354414411f548666 100644 (file)
@@ -16,7 +16,10 @@ import {
 import { compile } from '@vue/compiler-dom'
 import * as runtimeDom from '@vue/runtime-dom'
 import { RouteLocationNormalizedLoose } from './utils'
-import { routeLocationKey } from '../src/injectionSymbols'
+import {
+  routeLocationKey,
+  routerViewLocationKey,
+} from '../src/injectionSymbols'
 import { Router } from '../src'
 
 export interface MountOptions {
@@ -183,6 +186,7 @@ export function createMockedRoute(initialValue: RouteLocationNormalizedLoose) {
     set,
     provides: {
       [routeLocationKey as symbol]: value,
+      [routerViewLocationKey as symbol]: routeRef,
     },
   }
 }
index 2987cc66a5f456b1406a9fba4a5e5a7d8b2cd59e..1e35e35291e641606da829e579a7e9e132df427b 100644 (file)
@@ -47,6 +47,8 @@ const Home = defineComponent({
     </li>
   </ul>
 
+  <router-view />
+
   <dialog ref="modal" id="dialog">
     <div>
       <div v-if="userId">
@@ -110,6 +112,10 @@ const About = defineComponent({
   },
 })
 
+const Child = defineComponent({
+  template: `<div class="child">child</div>`,
+})
+
 const UserDetails = defineComponent({
   template: `<div>
     <h1>User #{{ id }}</h1>
@@ -121,8 +127,7 @@ const UserDetails = defineComponent({
   props: {
     id: {
       type: String,
-      // FIXME: setting this to true fails with props: true, as if it didn't fit the definition of RouteComponent
-      required: false,
+      required: true,
     },
   },
   data: () => ({ users }),
@@ -132,7 +137,14 @@ const webHistory = createWebHistory('/' + __dirname)
 const router = createRouter({
   history: webHistory,
   routes: [
-    { path: '/', component: Home },
+    {
+      path: '/',
+      component: Home,
+      children: [
+        // to check that displaying the modal doesn't change this
+        { path: '', component: Child },
+      ],
+    },
     { path: '/about', component: About },
     { path: '/users/:id', props: true, name: 'user', component: UserDetails },
   ],
index 236ac67e44c2231f44237de326b464bb1f12d5cf..f47e368603ef98706255b1c67fcb7ed0840e6fc5 100644 (file)
@@ -14,11 +14,13 @@ module.exports = {
       .waitForElementPresent('#app > *', 1000)
       .assert.containsText('h1', 'Home')
       .assert.not.visible('dialog')
+      .assert.containsText('.child', 'child')
 
       .click('li:nth-child(2) button')
       .assert.urlEquals(baseURL + '/users/1')
       .assert.visible('dialog')
       .assert.containsText('dialog', 'User #1')
+      .assert.containsText('.child', 'child')
 
       .end()
   },
index 323b2d14f420b80b901d9832bc169b2571ca54e5..f491d4f155472b682520a5a924eeb234c7349d55 100644 (file)
@@ -22,7 +22,7 @@ import {
 import {
   matchedRouteKey,
   viewDepthKey,
-  routeLocationKey,
+  routerViewLocationKey,
 } from './injectionSymbols'
 import { assign } from './utils'
 import { warn } from './warning'
@@ -47,14 +47,16 @@ export const RouterViewImpl = /*#__PURE__*/ defineComponent({
   setup(props, { attrs, slots }) {
     __DEV__ && warnDeprecatedUsage()
 
-    const injectedRoute = inject(routeLocationKey)!
+    const injectedRoute = inject(routerViewLocationKey)!
+    const routeToDisplay = computed(() => props.route || injectedRoute.value)
     const depth = inject(viewDepthKey, 0)
     const matchedRouteRef = computed<RouteLocationMatched | undefined>(
-      () => (props.route || injectedRoute).matched[depth]
+      () => routeToDisplay.value.matched[depth]
     )
 
     provide(viewDepthKey, depth + 1)
     provide(matchedRouteKey, matchedRouteRef)
+    provide(routerViewLocationKey, routeToDisplay)
 
     const viewRef = ref<ComponentPublicInstance>()
 
@@ -93,7 +95,7 @@ export const RouterViewImpl = /*#__PURE__*/ defineComponent({
     )
 
     return () => {
-      const route = props.route || injectedRoute
+      const route = routeToDisplay.value
       const matchedRoute = matchedRouteRef.value
       const ViewComponent = matchedRoute && matchedRoute.components[props.name]
       // we need the value at the time we render because when we unmount, we
index b23ea5e376772022280a27865a078627ccf97b2f..0d345ea1f9ad12ba7df2027675cfa21c81d8520f 100644 (file)
@@ -1,4 +1,4 @@
-import { InjectionKey, ComputedRef } from 'vue'
+import { InjectionKey, ComputedRef, Ref } from 'vue'
 import { RouteLocationNormalizedLoaded } from './types'
 import { Router } from './router'
 import { RouteRecordNormalized } from './matcher/types'
@@ -35,7 +35,8 @@ export const viewDepthKey = /*#__PURE__*/ PolySymbol(
 ) as InjectionKey<number>
 
 /**
- * Allows overriding the router instance returned by `useRouter` in tests. r stands for router
+ * Allows overriding the router instance returned by `useRouter` in tests. r
+ * stands for router
  *
  * @internal
  */
@@ -44,10 +45,21 @@ export const routerKey = /*#__PURE__*/ PolySymbol(
 ) as InjectionKey<Router>
 
 /**
- * Allows overriding the current route returned by `useRoute` in tests. rl stands for route location
+ * Allows overriding the current route returned by `useRoute` in tests. rl
+ * stands for route location
  *
  * @internal
  */
 export const routeLocationKey = /*#__PURE__*/ PolySymbol(
   __DEV__ ? 'route location' : 'rl'
 ) as InjectionKey<RouteLocationNormalizedLoaded>
+
+/**
+ * Allows overriding the current route used by router-view. Internally this is
+ * used when the `route` prop is passed.
+ *
+ * @internal
+ */
+export const routerViewLocationKey = /*#__PURE__*/ PolySymbol(
+  __DEV__ ? 'router view location' : 'rvl'
+) as InjectionKey<Ref<RouteLocationNormalizedLoaded>>
index 7aa5490fcb3242123289e0b8823d278d43996e78..15aa574887d2ade374af5809998ea8a5922710f4 100644 (file)
@@ -56,7 +56,11 @@ import { extractComponentsGuards, guardToPromiseFn } from './navigationGuards'
 import { warn } from './warning'
 import { RouterLink } from './RouterLink'
 import { RouterView } from './RouterView'
-import { routerKey, routeLocationKey } from './injectionSymbols'
+import {
+  routeLocationKey,
+  routerKey,
+  routerViewLocationKey,
+} from './injectionSymbols'
 import { addDevtools } from './devtools'
 
 /**
@@ -1098,6 +1102,7 @@ export function createRouter(options: RouterOptions): Router {
 
       app.provide(routerKey, router)
       app.provide(routeLocationKey, reactive(reactiveRoute))
+      app.provide(routerViewLocationKey, currentRoute)
 
       let unmountApp = app.unmount
       installedApps.add(app)