Skip to content

Commit 64785a9

Browse files
Domino9697posva
authored andcommitted
fix(link): Fix active links when parent link redirects to child (#2772)
* fix(ActiveLink): Fix active links when parent link redirects to child Fix active parent link when parent link redirects to a child and when the user navigates between child links fix #2724 * test(active-links): add more tests for redirects * chore(lint): add prettier conf to specs for longer lines * test(active-links): adapt redirect tests to added content * chore(link): remove commented code
1 parent da1a114 commit 64785a9

File tree

4 files changed

+93
-21
lines changed

4 files changed

+93
-21
lines changed

examples/active-links/app.js

+44-2
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,48 @@ const Users = {
1717

1818
const User = { template: '<div>{{ $route.params.username }}</div>' }
1919

20+
const Gallery = {
21+
template: `
22+
<div>
23+
<h2>Gallery</h2>
24+
<router-view></router-view>
25+
</div>
26+
`
27+
}
28+
29+
const Image = { template: '<div>{{ $route.params.imageId }}</div>' }
30+
2031
const router = new VueRouter({
2132
mode: 'history',
2233
base: __dirname,
2334
routes: [
2435
{ path: '/', component: Home },
2536
{ path: '/about', component: About },
26-
{ path: '/users', component: Users,
37+
{
38+
path: '/redirect-gallery',
39+
name: 'redirect-gallery',
40+
redirect: { name: 'gallery' }
41+
},
42+
{
43+
path: '/redirect-image',
44+
name: 'redirect-image',
45+
redirect: { name: 'image', params: { imageId: 'image1' }}
46+
},
47+
{
48+
path: '/users',
49+
component: Users,
50+
children: [{ path: ':username', name: 'user', component: User }]
51+
},
52+
{
53+
path: '/gallery',
54+
component: Gallery,
2755
children: [
28-
{ path: ':username', name: 'user', component: User }
56+
{
57+
path: '',
58+
name: 'gallery',
59+
redirect: { name: 'image', params: { imageId: 'image1' }}
60+
},
61+
{ path: ':imageId', component: Image, name: 'image' }
2962
]
3063
}
3164
]
@@ -66,6 +99,15 @@ new Vue({
6699
<router-link tag="li" to="/about">
67100
<a>/about (active class on outer element)</a>
68101
</router-link>
102+
103+
<li><router-link to="/gallery">/gallery (redirect to /gallery/image1)</router-link></li>
104+
<li><router-link :to="{ name: 'gallery' }">/gallery named link (redirect to /gallery/image1)</router-link></li>
105+
<li><router-link :to="{ name: 'image', params: {imageId: 'image2'} }">/gallery/image2</router-link></li>
106+
<li><router-link :to="{ name: 'image', params: {imageId: 'image1'} }">/gallery/image1</router-link></li>
107+
<li><router-link to="/redirect-gallery">/redirect-gallery (redirect to /gallery)</router-link></li>
108+
<li><router-link :to="{ name: 'redirect-gallery' }">/redirect-gallery named (redirect to /gallery)</router-link></li>
109+
<li><router-link to="/redirect-image">/redirect-image (redirect to /gallery/image1)</router-link></li>
110+
<li><router-link :to="{ name: 'redirect-image' }" >/redirect-image named (redirect to /gallery/image1)</router-link></li>
69111
</ul>
70112
<router-view class="view"></router-view>
71113
</div>

src/components/link.js

+26-18
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { createRoute, isSameRoute, isIncludedRoute } from '../util/route'
44
import { extend } from '../util/misc'
5+
import { normalizeLocation } from '../util/location'
56

67
// work around weird flow bug
78
const toTypes: Array<Function> = [String, Object]
@@ -31,26 +32,31 @@ export default {
3132
render (h: Function) {
3233
const router = this.$router
3334
const current = this.$route
34-
const { location, route, href } = router.resolve(this.to, current, this.append)
35+
const { location, route, href } = router.resolve(
36+
this.to,
37+
current,
38+
this.append
39+
)
3540

3641
const classes = {}
3742
const globalActiveClass = router.options.linkActiveClass
3843
const globalExactActiveClass = router.options.linkExactActiveClass
3944
// Support global empty active class
40-
const activeClassFallback = globalActiveClass == null
41-
? 'router-link-active'
42-
: globalActiveClass
43-
const exactActiveClassFallback = globalExactActiveClass == null
44-
? 'router-link-exact-active'
45-
: globalExactActiveClass
46-
const activeClass = this.activeClass == null
47-
? activeClassFallback
48-
: this.activeClass
49-
const exactActiveClass = this.exactActiveClass == null
50-
? exactActiveClassFallback
51-
: this.exactActiveClass
52-
const compareTarget = location.path
53-
? createRoute(null, location, null, router)
45+
const activeClassFallback =
46+
globalActiveClass == null ? 'router-link-active' : globalActiveClass
47+
const exactActiveClassFallback =
48+
globalExactActiveClass == null
49+
? 'router-link-exact-active'
50+
: globalExactActiveClass
51+
const activeClass =
52+
this.activeClass == null ? activeClassFallback : this.activeClass
53+
const exactActiveClass =
54+
this.exactActiveClass == null
55+
? exactActiveClassFallback
56+
: this.exactActiveClass
57+
58+
const compareTarget = route.redirectedFrom
59+
? createRoute(null, normalizeLocation(route.redirectedFrom), null, router)
5460
: route
5561

5662
classes[exactActiveClass] = isSameRoute(current, compareTarget)
@@ -70,7 +76,9 @@ export default {
7076

7177
const on = { click: guardEvent }
7278
if (Array.isArray(this.event)) {
73-
this.event.forEach(e => { on[e] = handler })
79+
this.event.forEach(e => {
80+
on[e] = handler
81+
})
7482
} else {
7583
on[this.event] = handler
7684
}
@@ -88,9 +96,9 @@ export default {
8896
if (a) {
8997
// in case the <a> is a static node
9098
a.isStatic = false
91-
const aData = a.data = extend({}, a.data)
99+
const aData = (a.data = extend({}, a.data))
92100
aData.on = on
93-
const aAttrs = a.data.attrs = extend({}, a.data.attrs)
101+
const aAttrs = (a.data.attrs = extend({}, a.data.attrs))
94102
aAttrs.href = href
95103
} else {
96104
// doesn't have <a> child, apply listener to self

test/e2e/specs/.prettierrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"printWidth": 120
3+
}

test/e2e/specs/active-links.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module.exports = {
99
browser
1010
.url('http://localhost:8080/active-links/')
1111
.waitForElementVisible('#app', 1000)
12-
.assert.count('li a', 11)
12+
.assert.count('li a', 19)
1313
// assert correct href with base
1414
.assert.attributeContains('li:nth-child(1) a', 'href', '/active-links/')
1515
.assert.attributeContains('li:nth-child(2) a', 'href', '/active-links/')
@@ -22,6 +22,14 @@ module.exports = {
2222
.assert.attributeContains('li:nth-child(9) a', 'href', '/active-links/users/evan?foo=bar&baz=qux')
2323
.assert.attributeContains('li:nth-child(10) a', 'href', '/active-links/about')
2424
.assert.attributeContains('li:nth-child(11) a', 'href', '/active-links/about')
25+
.assert.attributeContains('li:nth-child(12) a', 'href', '/active-links/gallery')
26+
.assert.attributeContains('li:nth-child(13) a', 'href', '/active-links/gallery/')
27+
.assert.attributeContains('li:nth-child(14) a', 'href', '/active-links/gallery/image2')
28+
.assert.attributeContains('li:nth-child(15) a', 'href', '/active-links/gallery/image1')
29+
.assert.attributeContains('li:nth-child(16) a', 'href', '/active-links/redirect-gallery')
30+
.assert.attributeContains('li:nth-child(17) a', 'href', '/active-links/redirect-gallery')
31+
.assert.attributeContains('li:nth-child(18) a', 'href', '/active-links/redirect-image')
32+
.assert.attributeContains('li:nth-child(19) a', 'href', '/active-links/redirect-image')
2533
.assert.containsText('.view', 'Home')
2634

2735
assertActiveLinks(1, [1, 2], null, [1, 2])
@@ -36,6 +44,17 @@ module.exports = {
3644
assertActiveLinks(10, [1, 10], [11], [10], [11])
3745
assertActiveLinks(11, [1, 10], [11], [10], [11])
3846

47+
// redirects
48+
assertActiveLinks(12, [1, 12, 13, 15], null, [15])
49+
assertActiveLinks(13, [1, 12, 13, 15], null, [15])
50+
assertActiveLinks(14, [1, 12, 13, 14], null, [14])
51+
assertActiveLinks(15, [1, 12, 13, 15], null, [15])
52+
// different level redirect
53+
assertActiveLinks(16, [1, 12, 13, 15], null, [15])
54+
assertActiveLinks(17, [1, 12, 13, 15], null, [15])
55+
assertActiveLinks(18, [1, 12, 13, 15], null, [15])
56+
assertActiveLinks(19, [1, 12, 13, 15], null, [15])
57+
3958
browser.end()
4059

4160
function assertActiveLinks (n, activeA, activeLI, exactActiveA, exactActiveLI) {

0 commit comments

Comments
 (0)