@@ -11,9 +11,12 @@ import {
11
11
computed ,
12
12
AllowedComponentProps ,
13
13
ComponentCustomProps ,
14
- watch ,
15
14
} from 'vue'
16
- import { RouteLocationNormalized , RouteLocationNormalizedLoaded } from './types'
15
+ import {
16
+ RouteLocationNormalized ,
17
+ RouteLocationNormalizedLoaded ,
18
+ RouteLocationMatched ,
19
+ } from './types'
17
20
import {
18
21
matchedRouteKey ,
19
22
viewDepthKey ,
@@ -43,7 +46,7 @@ export const RouterViewImpl = defineComponent({
43
46
44
47
const injectedRoute = inject ( routeLocationKey ) !
45
48
const depth = inject ( viewDepthKey , 0 )
46
- const matchedRouteRef = computed (
49
+ const matchedRouteRef = computed < RouteLocationMatched | undefined > (
47
50
( ) => ( props . route || injectedRoute ) . matched [ depth ]
48
51
)
49
52
@@ -55,35 +58,39 @@ export const RouterViewImpl = defineComponent({
55
58
// when the same component is used in different routes, the onVnodeMounted
56
59
// hook doesn't trigger, so we need to observe the changing route to update
57
60
// the instance on the record
58
- watch ( matchedRouteRef , to => {
59
- const currentName = props . name
60
- // to can be null if there isn't a matched route, e.g. not found
61
- if ( to && ! to . instances [ currentName ] ) {
62
- to . instances [ currentName ] = viewRef . value
63
- // trigger enter callbacks when different routes only
64
- if ( viewRef . value ) {
65
- ; ( to . enterCallbacks [ currentName ] || [ ] ) . forEach ( callback =>
66
- callback ( viewRef . value ! )
67
- )
68
- // avoid double calls since watch is called before the onVnodeMounted
69
- to . enterCallbacks [ currentName ] = [ ]
70
- }
71
- }
72
- } )
61
+ // watch(matchedRouteRef, to => {
62
+ // const currentName = props.name
63
+ // // to can be null if there isn't a matched route, e.g. not found
64
+ // if (to && !to.instances[currentName]) {
65
+ // to.instances[currentName] = viewRef.value
66
+ // // trigger enter callbacks when different routes only
67
+ // if (viewRef.value) {
68
+ // ;(to.enterCallbacks[currentName] || []).forEach(callback =>
69
+ // callback(viewRef.value!)
70
+ // )
71
+ // // avoid double calls since watch is called before the onVnodeMounted
72
+ // to.enterCallbacks[currentName] = []
73
+ // }
74
+ // }
75
+ // })
73
76
74
77
return ( ) => {
75
78
const route = props . route || injectedRoute
76
79
const matchedRoute = matchedRouteRef . value
77
80
const ViewComponent = matchedRoute && matchedRoute . components [ props . name ]
81
+ // we need the value at the time we render because when we unmount, we
82
+ // navigated to a different location so the value is different
83
+ const currentName = props . name
84
+ const key = matchedRoute && currentName + matchedRoute . path
78
85
79
86
if ( ! ViewComponent ) {
80
87
return slots . default
81
- ? slots . default ( { Component : ViewComponent , route } )
88
+ ? slots . default ( { Component : ViewComponent , route, key } )
82
89
: null
83
90
}
84
91
85
92
// props from route configuration
86
- const routePropsOption = matchedRoute . props [ props . name ]
93
+ const routePropsOption = matchedRoute ! . props [ props . name ]
87
94
const routeProps = routePropsOption
88
95
? routePropsOption === true
89
96
? route . params
@@ -92,23 +99,20 @@ export const RouterViewImpl = defineComponent({
92
99
: routePropsOption
93
100
: null
94
101
95
- // we need the value at the time we render because when we unmount, we
96
- // navigated to a different location so the value is different
97
- const currentName = props . name
98
102
const onVnodeMounted = ( ) => {
99
- matchedRoute . instances [ currentName ] = viewRef . value
100
- ; ( matchedRoute . enterCallbacks [ currentName ] || [ ] ) . forEach ( callback =>
103
+ matchedRoute ! . instances [ currentName ] = viewRef . value
104
+ ; ( matchedRoute ! . enterCallbacks [ currentName ] || [ ] ) . forEach ( callback =>
101
105
callback ( viewRef . value ! )
102
106
)
103
107
}
104
108
const onVnodeUnmounted = ( ) => {
105
109
// remove the instance reference to prevent leak
106
- matchedRoute . instances [ currentName ] = null
110
+ matchedRoute ! . instances [ currentName ] = null
107
111
}
108
112
109
113
const component = h (
110
114
ViewComponent ,
111
- assign ( { } , routeProps , attrs , {
115
+ assign ( { key } , routeProps , attrs , {
112
116
onVnodeMounted,
113
117
onVnodeUnmounted,
114
118
ref : viewRef ,
@@ -119,7 +123,7 @@ export const RouterViewImpl = defineComponent({
119
123
// pass the vnode to the slot as a prop.
120
124
// h and <component :is="..."> both accept vnodes
121
125
slots . default
122
- ? slots . default ( { Component : component , route } )
126
+ ? slots . default ( { Component : component , route, key } )
123
127
: component
124
128
)
125
129
}
0 commit comments