Skip to content

Commit 4f42085

Browse files
committed
v-link: changes to active class matching. add exactMatch and activeClass options
1 parent 0f50096 commit 4f42085

File tree

4 files changed

+38
-31
lines changed

4 files changed

+38
-31
lines changed

src/directives/link.js

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,16 @@ export default function (Vue) {
5757

5858
update (path) {
5959
let router = this.vm.$route.router
60-
this.replace = typeof path === 'object' ? path.replace : false
60+
if (typeof path === 'object') {
61+
this.replace = path.replace
62+
this.exact = path.exactMatch
63+
this.prevActiveClass = this.activeClass
64+
this.activeClass = path.activeClass
65+
}
6166
path = router._normalizePath(path)
6267
this.destination = path
63-
this.activeRE = path
64-
? path === '/'
65-
? /^\/$/
66-
: new RegExp('^' + path.replace(regexEscapeRE, '\\$&') + '(\\b|$)')
68+
this.activeRE = path && !this.exact
69+
? new RegExp('^' + path.replace(regexEscapeRE, '\\$&') + '(\\b|$)')
6770
: null
6871
this.updateClasses(this.vm.$route.path)
6972
let isAbsolute = path.charAt(0) === '/'
@@ -84,18 +87,25 @@ export default function (Vue) {
8487
let el = this.el
8588
let dest = this.destination
8689
let router = this.vm.$route.router
87-
let activeClass = router._linkActiveClass
88-
let exactClass = router._linkActiveExactClass
89-
if (this.activeRE &&
90-
this.activeRE.test(path)) {
91-
_.addClass(el, activeClass)
92-
} else {
93-
_.removeClass(el, activeClass)
90+
let activeClass = this.activeClass || router._linkActiveClass
91+
// clear old class
92+
if (this.prevActiveClass !== activeClass) {
93+
_.removeClass(el, this.prevActiveClass)
9494
}
95-
if (path === dest) {
96-
_.addClass(el, exactClass)
95+
// add new class
96+
if (this.exact) {
97+
if (path === dest) {
98+
_.addClass(el, activeClass)
99+
} else {
100+
_.removeClass(el, activeClass)
101+
}
97102
} else {
98-
_.removeClass(el, exactClass)
103+
if (this.activeRE &&
104+
this.activeRE.test(path)) {
105+
_.addClass(el, activeClass)
106+
} else {
107+
_.removeClass(el, activeClass)
108+
}
99109
}
100110
},
101111

src/index.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ class Router {
3434
transitionOnLoad = false,
3535
suppressTransitionError = false,
3636
root = null,
37-
linkActiveClass = 'v-link-active',
38-
linkActiveExactClass = 'v-link-active-exact'
37+
linkActiveClass = 'v-link-active'
3938
} = {}) {
4039

4140
/* istanbul ignore if */
@@ -83,7 +82,6 @@ class Router {
8382
// other options
8483
this._saveScrollPosition = saveScrollPosition
8584
this._linkActiveClass = linkActiveClass
86-
this._linkActiveExactClass = linkActiveExactClass
8785
this._suppress = suppressTransitionError
8886

8987
// create history object

test/e2e/test.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module.exports = {
1515
.waitForElementVisible('h1', 1000)
1616
.assert.containsText('.view h2', 'ABOUT US')
1717
.assert.cssClassPresent('a[href="/about"]', 'v-link-active')
18-
.assert.cssClassPresent('a[href="/about"]', 'v-link-active-exact')
1918
// should not be able to navigate to inbox
2019
.click('a[href^="/inbox"]')
2120
.pause(100)
@@ -26,7 +25,6 @@ module.exports = {
2625
// should not have changed
2726
.assert.containsText('.view h2', 'ABOUT US')
2827
.assert.cssClassPresent('a[href="/about"]', 'v-link-active')
29-
.assert.cssClassPresent('a[href="/about"]', 'v-link-active-exact')
3028

3129
// /user
3230
.url(base + '/user/1234/profile/what')
@@ -35,7 +33,6 @@ module.exports = {
3533
.assert.containsText('.view h3', 'user profile')
3634
.assert.containsText('.view p', '1234 what')
3735
.assert.cssClassPresent('a[href^="/user"]', 'v-link-active')
38-
.assert.cssClassPresent('a[href^="/user"]', 'v-link-active-exact')
3936
// change params
4037
.execute(function () {
4138
router.go('/user/2345/profile/hey')
@@ -97,7 +94,6 @@ module.exports = {
9794
.waitForElementVisible('h1', 1000)
9895
.assert.containsText('.view h2', 'ABOUT US')
9996
.assert.cssClassPresent('a[href="/about"]', 'v-link-active')
100-
.assert.cssClassPresent('a[href="/about"]', 'v-link-active-exact')
10197
.end()
10298
}
10399
}

test/unit/specs/core.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,17 @@ describe('Core', function () {
216216
it('v-link active classes', function (done) {
217217
router = new Router({
218218
abstract: true,
219-
linkActiveClass: 'active',
220-
linkActiveExactClass: 'active-exact'
219+
linkActiveClass: 'active'
221220
})
222221
var App = Vue.extend({
223222
replace: false,
223+
data: function () {
224+
return { className: 'custom' }
225+
},
224226
template:
225227
'<a id="link-a" v-link="{ path: \'/a\' }">Link A</a>' +
226-
'<a id="link-b" v-link="{ path: \'/b\' }">Link B</a>' +
227-
'<a id="link-c" v-link="{ path: \'/\' }">Link C</a>' +
228+
'<a id="link-b" v-link="{ path: \'/b\', activeClass: className }">Link B</a>' +
229+
'<a id="link-c" v-link="{ path: \'/\', exactMatch: true }">Link C</a>' +
228230
'<router-view></router-view>'
229231
})
230232
router.start(App, el)
@@ -234,26 +236,27 @@ describe('Core', function () {
234236
var linkC = el.querySelector('#link-c')
235237
expect(linkA.className).toBe('')
236238
expect(linkB.className).toBe('')
237-
expect(linkC.className).toBe('active active-exact')
239+
expect(linkC.className).toBe('active')
238240
router.go('/a')
239241
nextTick(function () {
240-
expect(linkA.className).toBe('active active-exact')
242+
expect(linkA.className).toBe('active')
241243
expect(linkB.className).toBe('')
242244
expect(linkC.className).toBe('')
243245
router.go('/a/b/c')
244246
nextTick(function () {
245247
expect(linkA.className).toBe('active')
246248
expect(linkB.className).toBe('')
247-
// expect(linkC.className).toBe('')
249+
expect(linkC.className).toBe('')
248250
router.go('/b')
249251
nextTick(function () {
250252
expect(linkA.className).toBe('')
251-
expect(linkB.className).toBe('active active-exact')
253+
expect(linkB.className).toBe('custom')
252254
expect(linkC.className).toBe('')
255+
router.app.className = 'changed'
253256
router.go('/b/c/d')
254257
nextTick(function () {
255258
expect(linkA.className).toBe('')
256-
expect(linkB.className).toBe('active')
259+
expect(linkB.className).toBe('changed')
257260
expect(linkC.className).toBe('')
258261
router.go('/bcd')
259262
nextTick(function () {

0 commit comments

Comments
 (0)