@@ -11,7 +11,6 @@ import { slot } from '../../utils/private/slot.js'
1111import cache from '../../utils/private/cache.js'
1212import { rtlHasScrollBug } from '../../utils/scroll.js'
1313import { injectProp } from '../../utils/private/inject-obj-prop.js'
14- import { isDeepEqual } from '../../utils/is.js'
1514
1615function getIndicatorClass ( color , top , vertical ) {
1716 const pos = vertical === true
@@ -22,18 +21,16 @@ function getIndicatorClass (color, top, vertical) {
2221}
2322
2423const alignValues = [ 'left' , 'center' , 'right' , 'justify' ]
25- const getDefaultBestScore = ( ) => ( { matchedLen : 0 , queryScore : 0 , hrefLen : 0 , exact : false , redirected : true } )
26-
27- function getQueryScore ( targetQuery , matchingQuery ) {
28- let score = 0
24+ const getDefaultBestScore = ( ) => ( { matchedLen : 0 , queryDiff : 9999 , hrefLen : 0 , exact : false , redirected : true } )
2925
26+ function hasQueryIncluded ( targetQuery , matchingQuery ) {
3027 for ( const key in targetQuery ) {
31- if ( isDeepEqual ( targetQuery [ key ] , matchingQuery [ key ] ) === true ) {
32- score ++
28+ if ( targetQuery [ key ] !== matchingQuery [ key ] ) {
29+ return false
3330 }
3431 }
3532
36- return score
33+ return true
3734}
3835
3936export default Vue . extend ( {
@@ -448,9 +445,13 @@ export default Vue.extend({
448445 // do not use directly; use __verifyRouteModel() instead
449446 __updateActiveRoute ( ) {
450447 let name = null , bestScore = getDefaultBestScore ( )
448+
451449 const vmList = this . tabVmList . filter ( tab => tab . hasRouterLink === true )
452450 const vmLen = vmList . length
453451
452+ const { query : currentQuery } = this . $route
453+ const currentQueryLen = Object . keys ( currentQuery ) . length
454+
454455 for ( let tabIndex = 0 ; tabIndex < vmLen ; tabIndex ++ ) {
455456 const tab = vmList [ tabIndex ]
456457 const exact = tab . exact === true
@@ -466,7 +467,7 @@ export default Vue.extend({
466467 }
467468
468469 const { route, href } = tab . resolvedLink
469- const { hash , matched, query } = route
470+ const { matched, query, hash } = route
470471 const redirected = route . redirectedFrom !== void 0
471472
472473 if ( exact === true ) {
@@ -489,13 +490,26 @@ export default Vue.extend({
489490 continue
490491 }
491492
493+ const queryLen = Object . keys ( query ) . length
494+
495+ if (
496+ // if it's exact it already perfectly includes current query
497+ // so no point in computing it
498+ exact === false &&
499+ queryLen !== 0 &&
500+ hasQueryIncluded ( query , currentQuery ) === false
501+ ) {
502+ // it has query and it doesn't includes the current one
503+ continue
504+ }
505+
492506 const newScore = {
493507 exact,
494508 redirected,
495509 matchedLen : matched . length ,
496- queryScore : exact === true
497- ? 0 // avoid computing as it's maximum anyway
498- : getQueryScore ( query , this . $route . query ) ,
510+ queryDiff : exact === true
511+ ? 0 // avoid computing as it's 0 anyway
512+ : currentQueryLen - queryLen ,
499513 hrefLen : href . length - hash . length
500514 }
501515
@@ -510,14 +524,13 @@ export default Vue.extend({
510524 continue
511525 }
512526
513- if ( newScore . queryScore > bestScore . queryScore ) {
527+ if ( newScore . queryDiff < bestScore . queryDiff ) {
514528 // query is closer to the current one so we set it as current champion
515529 name = tab . name
516530 bestScore = newScore
517531 continue
518532 }
519- else if ( newScore . queryScore !== bestScore . queryScore ) {
520- // query is farther away than current champion so we discard it
533+ else if ( newScore . queryDiff !== bestScore . queryDiff ) {
521534 continue
522535 }
523536
0 commit comments