@@ -9,17 +9,41 @@ export default function (Vue) {
9
9
10
10
const {
11
11
bind,
12
+ getAttr,
12
13
isObject,
13
14
addClass,
14
15
removeClass
15
16
} = Vue . util
16
17
17
18
const onPriority = Vue . directive ( 'on' ) . priority
19
+ const LINK_UPDATE = '__vue-router-link-update__'
20
+
21
+ let activeId = 0
18
22
19
23
Vue . directive ( 'link-active' , {
20
- priority : onPriority - 1 ,
24
+ priority : 9999 ,
21
25
bind ( ) {
22
- this . el . __v_link_active = true
26
+ const id = String ( activeId ++ )
27
+ // collect v-links contained within this element.
28
+ // we need do this here before the parent-child relationship
29
+ // gets messed up by terminal directives (if, for, components)
30
+ const childLinks = this . el . querySelectorAll ( '[v-link]' )
31
+ for ( var i = 0 , l = childLinks . length ; i < l ; i ++ ) {
32
+ let link = childLinks [ i ]
33
+ let existingId = link . getAttribute ( LINK_UPDATE )
34
+ let value = existingId ? ( existingId + ',' + id ) : id
35
+ // leave a mark on the link element which can be persisted
36
+ // through fragment clones.
37
+ link . setAttribute ( LINK_UPDATE , value )
38
+ }
39
+ this . vm . $on ( LINK_UPDATE , this . cb = ( link , path ) => {
40
+ if ( link . activeIds . indexOf ( id ) > - 1 ) {
41
+ link . updateClasses ( path , this . el )
42
+ }
43
+ } )
44
+ } ,
45
+ unbind ( ) {
46
+ this . vm . $off ( LINK_UPDATE , this . cb )
23
47
}
24
48
} )
25
49
@@ -36,15 +60,10 @@ export default function (Vue) {
36
60
this . router = vm . $route . router
37
61
// update things when the route changes
38
62
this . unwatch = vm . $watch ( '$route' , bind ( this . onRouteUpdate , this ) )
39
- // check if active classes should be applied to a different element
40
- this . activeEl = this . el
41
- var parent = this . el . parentNode
42
- while ( parent ) {
43
- if ( parent . __v_link_active ) {
44
- this . activeEl = parent
45
- break
46
- }
47
- parent = parent . parentNode
63
+ // check v-link-active ids
64
+ const activeIds = getAttr ( this . el , LINK_UPDATE )
65
+ if ( activeIds ) {
66
+ this . activeIds = activeIds . split ( ',' )
48
67
}
49
68
// no need to handle click if link expects to be opened
50
69
// in a new window/tab.
@@ -115,7 +134,11 @@ export default function (Vue) {
115
134
this . updateActiveMatch ( )
116
135
this . updateHref ( )
117
136
}
118
- this . updateClasses ( route . path )
137
+ if ( this . activeIds ) {
138
+ this . vm . $emit ( LINK_UPDATE , this , route . path )
139
+ } else {
140
+ this . updateClasses ( route . path , this . el )
141
+ }
119
142
} ,
120
143
121
144
updateActiveMatch ( ) {
@@ -149,8 +172,7 @@ export default function (Vue) {
149
172
}
150
173
} ,
151
174
152
- updateClasses ( path ) {
153
- const el = this . activeEl
175
+ updateClasses ( path , el ) {
154
176
const activeClass = this . activeClass || this . router . _linkActiveClass
155
177
// clear old class
156
178
if ( this . prevActiveClass !== activeClass ) {
0 commit comments