Skip to content

Commit 6603aa2

Browse files
committed
feat(QTabs): tweak updateActiveRoute + improve tabs-router example
1 parent 0c77106 commit 6603aa2

2 files changed

Lines changed: 49 additions & 27 deletions

File tree

ui/dev/src/pages/components/tabs-router.vue

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div class="q-pa-md">
3-
<div class="q-gutter-y-md" style="max-width: 800px">
3+
<div class="q-gutter-y-md">
44
<div class="row q-col-gutter-md justify-stretch">
55
<div class="col-12">Router-links</div>
66

@@ -18,23 +18,32 @@
1818
</q-item>
1919
</div>
2020

21-
<q-item class="special-router-link" replace :to="{ query: { tab: '3', noScroll: true, y: '5' } }" active-class="special-router-link--active" exact-active-class="special-router-link--exact-active">
22-
<q-item-section>3 + y=5</q-item-section>
23-
</q-item>
24-
2521
<div class="col-12">Route query {{ $route.query }}</div>
22+
23+
<div>
24+
<q-item class="special-router-link" replace :to="{ query: { tab: '3', noScroll: true, y: '5' } }" active-class="special-router-link--active" exact-active-class="special-router-link--exact-active">
25+
<q-item-section>3 + y=5 - select 3*</q-item-section>
26+
</q-item>
27+
</div>
28+
29+
<div>
30+
<q-item class="special-router-link" replace :to="{ query: { tab: '3' } }" active-class="special-router-link--active" exact-active-class="special-router-link--exact-active">
31+
<q-item-section>{ tab: 3 } - select none</q-item-section>
32+
</q-item>
33+
</div>
2634
</div>
2735

2836
<q-tabs
2937
no-caps
3038
class="bg-orange text-white shadow-2"
3139
>
32-
<q-route-tab replace :to="{ query: { tab: '1', noScroll: true } }" label="[1] Activate in 2s" @click="navDelay" />
33-
<q-route-tab replace :to="{ query: { tab: '2', noScroll: true } }" label="[2] Do nothing" @click="navCancel" />
34-
<q-route-tab replace :to="{ query: { tab: '3', noScroll: true } }" label="[3] Navigate to the second tab" @click="navRedirect" />
35-
<q-route-tab replace :to="{ query: { tab: '4', noScroll: true } }" label="[4] Navigate immediately" @click="navPass" />
40+
<q-route-tab replace :to="{ query: { tab: '1', noScroll: true } }" label="[1*] Activate in 2s" @click="navDelay" />
41+
<q-route-tab replace :to="{ query: { tab: '2', noScroll: true } }" label="[2*] Do nothing" @click="navCancel" />
42+
<q-route-tab replace :to="{ query: { tab: '3', noScroll: true } }" label="[3*] Navigate to the second tab" @click="navRedirect" />
43+
<q-route-tab replace :to="{ query: { tab: '3', noScroll: true } }" exact label="[3] exact" @click="navPass" />
44+
<q-route-tab replace :to="{ query: { tab: '4', noScroll: true } }" label="[4*] Navigate immediately" @click="navPass" />
3645

37-
<q-route-tab replace :to="{ query: { tab: '5', noScroll: true } }" label="[5] With button" @click="navPass">
46+
<q-route-tab replace :to="{ query: { tab: '5', noScroll: true } }" label="[5*] With button" @click="navPass">
3847
<q-btn unelevated :label="`Click (${ clickCounter })`" @click.stop.prevent="onClick" />
3948
</q-route-tab>
4049
</q-tabs>
@@ -91,9 +100,9 @@ export default {
91100
text-align: center
92101
text-decoration: none
93102
color: black
94-
padding: 2px
103+
padding: 12px
95104
border: 1px solid black
96-
width: 50px
105+
min-width: 50px
97106
98107
&--active
99108
background-color: #ee9

ui/src/components/tabs/QTabs.js

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { slot } from '../../utils/private/slot.js'
1111
import cache from '../../utils/private/cache.js'
1212
import { rtlHasScrollBug } from '../../utils/scroll.js'
1313
import { injectProp } from '../../utils/private/inject-obj-prop.js'
14-
import { isDeepEqual } from '../../utils/is.js'
1514

1615
function getIndicatorClass (color, top, vertical) {
1716
const pos = vertical === true
@@ -22,18 +21,16 @@ function getIndicatorClass (color, top, vertical) {
2221
}
2322

2423
const 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

3936
export 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

Comments
 (0)