Skip to content

Commit b070bb2

Browse files
committed
feat: add destroy method, remove event listener on destroy
1 parent 23d87d8 commit b070bb2

File tree

5 files changed

+48
-23
lines changed

5 files changed

+48
-23
lines changed

src/history/base.js

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export class History {
2323
readyCbs: Array<Function>
2424
readyErrorCbs: Array<Function>
2525
errorCbs: Array<Function>
26+
removeEventListenerCbs: Array<Function>
2627

2728
// implemented by sub-classes
2829
+go: (n: number) => void
@@ -41,6 +42,7 @@ export class History {
4142
this.readyCbs = []
4243
this.readyErrorCbs = []
4344
this.errorCbs = []
45+
this.removeEventListenerCbs = []
4446
}
4547

4648
listen (cb: Function) {
@@ -208,6 +210,10 @@ export class History {
208210
hook && hook(route, prev)
209211
})
210212
}
213+
214+
destroy () {
215+
this.removeEventListenerCbs.forEach(cb => { cb() })
216+
}
211217
}
212218

213219
function normalizeBase (base: ?string): string {

src/history/hash.js

+22-18
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,30 @@ export class HashHistory extends History {
2525
const supportsScroll = supportsPushState && expectScroll
2626

2727
if (supportsScroll) {
28-
setupScroll()
28+
const uninstall = setupScroll()
29+
this.removeEventListenerCbs.push(uninstall)
2930
}
30-
31-
window.addEventListener(
32-
supportsPushState ? 'popstate' : 'hashchange',
33-
() => {
34-
const current = this.current
35-
if (!ensureSlash()) {
36-
return
37-
}
38-
this.transitionTo(getHash(), route => {
39-
if (supportsScroll) {
40-
handleScroll(this.router, route, current, true)
41-
}
42-
if (!supportsPushState) {
43-
replaceHash(route.fullPath)
44-
}
45-
})
31+
32+
const eventName = supportsPushState ? 'popstate' : 'hashchange'
33+
const listener = () => {
34+
const current = this.current
35+
if (!ensureSlash()) {
36+
return
4637
}
47-
)
38+
this.transitionTo(getHash(), route => {
39+
if (supportsScroll) {
40+
handleScroll(this.router, route, current, true)
41+
}
42+
if (!supportsPushState) {
43+
replaceHash(route.fullPath)
44+
}
45+
})
46+
}
47+
window.addEventListener(eventName, listener)
48+
const uninstall = () => {
49+
window.removeEventListener(eventName, listener)
50+
}
51+
this.removeEventListenerCbs.push(uninstall)
4852
}
4953

5054
push (location: RawLocation, onComplete?: Function, onAbort?: Function) {

src/history/html5.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ export class HTML5History extends History {
1515
const supportsScroll = supportsPushState && expectScroll
1616

1717
if (supportsScroll) {
18-
setupScroll()
18+
const uninstall = setupScroll()
19+
this.removeEventListenerCbs.push(uninstall)
1920
}
2021

2122
const initLocation = getLocation(this.base)
22-
window.addEventListener('popstate', e => {
23+
const listener = e => {
2324
const current = this.current
2425

2526
// Avoiding first `popstate` event dispatched in some browsers but first
@@ -34,7 +35,12 @@ export class HTML5History extends History {
3435
handleScroll(router, route, current, true)
3536
}
3637
})
37-
})
38+
}
39+
window.addEventListener('popstate', listener)
40+
const uninstall = () => {
41+
window.removeEventListener('popstate', listener)
42+
}
43+
this.removeEventListenerCbs.push(uninstall)
3844
}
3945

4046
go (n: number) {

src/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ export default class VueRouter {
239239
this.history.transitionTo(this.history.getCurrentLocation())
240240
}
241241
}
242+
243+
destroy () {
244+
this.history.destroy()
245+
}
242246
}
243247

244248
function registerHook (list: Array<any>, fn: Function): Function {

src/util/scroll.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@ export function setupScroll () {
1515
const protocolAndPath = window.location.protocol + '//' + window.location.host
1616
const absolutePath = window.location.href.replace(protocolAndPath, '')
1717
window.history.replaceState({ key: getStateKey() }, '', absolutePath)
18-
window.addEventListener('popstate', e => {
18+
const listener = e => {
1919
saveScrollPosition()
2020
if (e.state && e.state.key) {
2121
setStateKey(e.state.key)
2222
}
23-
})
23+
}
24+
window.addEventListener('popstate', listener)
25+
26+
return function uninstall () {
27+
window.removeEventListener('popstate', listener)
28+
}
2429
}
2530

2631
export function handleScroll (

0 commit comments

Comments
 (0)