Skip to content

Commit ab4b388

Browse files
committed
Merge branch 'link-delegate' into dev
2 parents 93e7a60 + cc0325e commit ab4b388

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

src/directives/link.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,26 @@ export default function (Vue) {
2626
// don't redirect when preventDefault called
2727
if (e.defaultPrevented) return
2828

29-
if (e.button === 0) {
29+
if (e.button !== 0) return
30+
31+
if (this.el.tagName === 'A') {
32+
// v-link on <a v-link="'path'">
3033
e.preventDefault()
3134
if (this.destination != null) {
3235
router.go(this.destination)
3336
}
37+
} else {
38+
// v-link delegate on <div v-link>
39+
var el = e.target
40+
while (el && el.tagName !== 'A' && el !== this.el) {
41+
el = el.parentNode
42+
}
43+
if (!el || el.tagName !== 'A' || !el.href) return
44+
45+
if (sameOrigin(el)) {
46+
e.preventDefault()
47+
router.go(el.href)
48+
}
3449
}
3550
}
3651
this.el.addEventListener('click', this.handler)
@@ -88,4 +103,10 @@ export default function (Vue) {
88103
this.unwatch && this.unwatch()
89104
}
90105
})
106+
107+
function sameOrigin (link) {
108+
return link.protocol === location.protocol &&
109+
link.hostname === location.hostname &&
110+
link.port === location.port
111+
}
91112
}

test/unit/specs/core.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,45 @@ describe('Core', function () {
292292
})
293293
})
294294

295+
it('v-link delegate', function (done) {
296+
router = new Router({ abstract: true })
297+
router.map({
298+
'/': {
299+
component: {
300+
template: '<div>Home</div>'
301+
}
302+
},
303+
'/foo': {
304+
component: {
305+
data: function () {
306+
return { home: '<a href="/">Link Home</a>' }
307+
},
308+
template: '<div id="wrap" v-html="home" v-link></div>'
309+
}
310+
}
311+
})
312+
var App = Vue.extend({
313+
replace: false,
314+
template: '<router-view></router-view>'
315+
})
316+
router.start(App, el)
317+
el = router.app.$el
318+
router.go('/foo')
319+
nextTick(function () {
320+
var wrap = el.querySelector('#wrap')
321+
var e = document.createEvent('HTMLEvents')
322+
// target is read-only
323+
e.target = wrap.querySelector('a')
324+
e.initEvent('click', true, true)
325+
wrap.dispatchEvent(e)
326+
nextTick(function () {
327+
var text = router.app.$el.textContent
328+
expect(text).toBe('Home')
329+
done()
330+
})
331+
})
332+
})
333+
295334
it('alias', function (done) {
296335
router = new Router({ abstract: true })
297336
router.map({

0 commit comments

Comments
 (0)