@@ -9,17 +9,41 @@ export default function (Vue) {
99
1010 const {
1111 bind,
12+ getAttr,
1213 isObject,
1314 addClass,
1415 removeClass
1516 } = Vue . util
1617
1718 const onPriority = Vue . directive ( 'on' ) . priority
19+ const LINK_UPDATE = '__vue-router-link-update__'
20+
21+ let activeId = 0
1822
1923 Vue . directive ( 'link-active' , {
20- priority : onPriority - 1 ,
24+ priority : 9999 ,
2125 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 )
2347 }
2448 } )
2549
@@ -36,15 +60,10 @@ export default function (Vue) {
3660 this . router = vm . $route . router
3761 // update things when the route changes
3862 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 ( ',' )
4867 }
4968 // no need to handle click if link expects to be opened
5069 // in a new window/tab.
@@ -115,7 +134,11 @@ export default function (Vue) {
115134 this . updateActiveMatch ( )
116135 this . updateHref ( )
117136 }
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+ }
119142 } ,
120143
121144 updateActiveMatch ( ) {
@@ -149,8 +172,7 @@ export default function (Vue) {
149172 }
150173 } ,
151174
152- updateClasses ( path ) {
153- const el = this . activeEl
175+ updateClasses ( path , el ) {
154176 const activeClass = this . activeClass || this . router . _linkActiveClass
155177 // clear old class
156178 if ( this . prevActiveClass !== activeClass ) {
0 commit comments