Skip to content

Commit 34044c5

Browse files
committed
simplify v-link onClick, fix v-link on non-anchor
1 parent 2d31613 commit 34044c5

File tree

2 files changed

+43
-31
lines changed

2 files changed

+43
-31
lines changed

src/directives/link.js

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const queryStringRE = /\?.*$/
77
// HTML5 history mode
88
export default function (Vue) {
99

10-
const urlParser = document.createElement('a')
1110
const {
1211
bind,
1312
isObject,
@@ -69,42 +68,29 @@ export default function (Vue) {
6968

7069
onClick (e) {
7170
// don't redirect with control keys
71+
/* istanbul ignore if */
7272
if (e.metaKey || e.ctrlKey || e.shiftKey) return
7373
// don't redirect when preventDefault called
74+
/* istanbul ignore if */
7475
if (e.defaultPrevented) return
7576
// don't redirect on right click
77+
/* istanbul ignore if */
7678
if (e.button !== 0) return
7779

7880
const target = this.target
79-
const go = (target) => {
81+
if (target) {
82+
// v-link with expression, just go
8083
e.preventDefault()
81-
if (target != null) {
82-
this.router.go(target)
83-
}
84-
}
85-
86-
if (this.el.tagName === 'A' || e.target === this.el) {
87-
// v-link on <a v-link="'path'">
88-
if (sameOrigin(this.el, target)) {
89-
go(target)
90-
} else if (typeof target === 'string') {
91-
window.location.href = target
92-
}
84+
this.router.go(target)
9385
} else {
94-
// v-link delegate on <div v-link>
86+
// no expression, delegate for an <a> inside
9587
var el = e.target
96-
while (el && el.tagName !== 'A' && el !== this.el) {
88+
while (el.tagName !== 'A' && el !== this.el) {
9789
el = el.parentNode
9890
}
99-
if (!el) return
100-
if (!sameOrigin(el, target) && typeof target === 'string') {
101-
window.location.href = target
102-
}
103-
if (el.tagName !== 'A' || !el.href) {
104-
// allow not anchor
105-
go(target)
106-
} else if (sameOrigin(el, target)) {
107-
go({
91+
if (el.tagName === 'A' && sameOrigin(el)) {
92+
e.preventDefault()
93+
this.router.go({
10894
path: el.pathname,
10995
replace: target && target.replace,
11096
append: target && target.append
@@ -196,12 +182,7 @@ export default function (Vue) {
196182
}
197183
})
198184

199-
function sameOrigin (link, target) {
200-
target = target || {}
201-
if (link.tagName !== 'A' && typeof target === 'string') {
202-
link = urlParser
203-
link.href = target
204-
}
185+
function sameOrigin (link) {
205186
return link.protocol === location.protocol &&
206187
link.hostname === location.hostname &&
207188
link.port === location.port

test/unit/specs/core.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,17 @@ describe('Core', function () {
88

99
beforeEach(function () {
1010
el = document.createElement('div')
11+
document.body.appendChild(el)
1112
spyOn(window, 'scrollTo')
1213
})
1314

15+
afterEach(function () {
16+
var el = router && router.app.$el
17+
if (el && document.body.contains(el)) {
18+
document.body.removeChild(el)
19+
}
20+
})
21+
1422
it('call Vue constructor with no arguments', function () {
1523
/* eslint-disable no-new */
1624
expect(function () {
@@ -322,6 +330,29 @@ describe('Core', function () {
322330
})
323331
})
324332

333+
it('v-link delegation', function (done) {
334+
router = new Router({ abstract: true })
335+
router.map({
336+
'/a': {
337+
component: {
338+
template: 'hello'
339+
}
340+
}
341+
})
342+
router.start({
343+
replace: false,
344+
template:
345+
'<div v-link><a id="link" href="/a"></a></div>' +
346+
'<router-view></router-view>'
347+
}, el)
348+
var link = el.querySelector('#link')
349+
click(link)
350+
nextTick(function () {
351+
expect(el.textContent).toBe('hello')
352+
done()
353+
})
354+
})
355+
325356
it('v-link active classes', function (done) {
326357
router = new Router({
327358
abstract: true,

0 commit comments

Comments
 (0)