From b8dad608bc5adf701db463dded99569cb4d02411 Mon Sep 17 00:00:00 2001 From: Volodymyr Makukha Date: Mon, 17 Aug 2020 11:11:55 +0300 Subject: [PATCH 1/4] feat(history): Reset history.current when all apps are destroyed --- src/history/base.js | 8 +++++++- src/index.js | 6 +----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/history/base.js b/src/history/base.js index 072cfb8e8..367c0bad5 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -252,11 +252,17 @@ export class History { // Default implementation is empty } - teardownListeners () { + teardown () { + // clean up event listeners + // https://github.com/vuejs/vue-router/issues/2341 this.listeners.forEach(cleanupListener => { cleanupListener() }) this.listeners = [] + + // reset current history route + // https://github.com/vuejs/vue-router/issues/3294 + this.current = START } } diff --git a/src/index.js b/src/index.js index 22ecff96d..3eda7f778 100644 --- a/src/index.js +++ b/src/index.js @@ -102,11 +102,7 @@ export default class VueRouter { // we do not release the router so it can be reused if (this.app === app) this.app = this.apps[0] || null - if (!this.app) { - // clean up event listeners - // https://github.com/vuejs/vue-router/issues/2341 - this.history.teardownListeners() - } + if (!this.app) this.history.teardown() }) // main app previously initialized From c779bbc9dffa7d30c76715a145f639f7390540a9 Mon Sep 17 00:00:00 2001 From: Volodymyr Makukha Date: Mon, 17 Aug 2020 16:01:38 +0300 Subject: [PATCH 2/4] test(history): adding restart-app test --- examples/index.html | 1 + examples/restart-app/app.js | 66 +++++++++++++++++++++++++++++++++ examples/restart-app/index.html | 21 +++++++++++ test/e2e/specs/restart-app.js | 45 ++++++++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 examples/restart-app/app.js create mode 100644 examples/restart-app/index.html create mode 100644 test/e2e/specs/restart-app.js diff --git a/examples/index.html b/examples/index.html index f9fbf1b9a..5f2cd4f32 100644 --- a/examples/index.html +++ b/examples/index.html @@ -29,6 +29,7 @@

Vue Router Examples

  • Nested Routers
  • Keepalive View
  • Multiple Apps
  • +
  • Restart App
  • diff --git a/examples/restart-app/app.js b/examples/restart-app/app.js new file mode 100644 index 000000000..424affe10 --- /dev/null +++ b/examples/restart-app/app.js @@ -0,0 +1,66 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' + +const Home = { template: '
    home
    ' } +const Foo = { template: '
    foo
    ' } + +const routes = [ + { path: '/', component: Home }, + { path: '/foo', component: Foo } +] + +const router = new VueRouter({ + mode: 'history', + base: __dirname, + routes +}) + +// track number of beforeResolve +const increment = name => { + const counter = document.getElementById(name) + counter.innerHTML++ +} + +document.getElementById('beforeEach').innerHTML = 0 +router.beforeEach((to, from, next) => { + increment('beforeEach') + next() +}) + +document.getElementById('beforeResolve').innerHTML = 0 +router.beforeResolve((to, from, next) => { + increment('beforeResolve') + next() +}) + +document.getElementById('afterEach').innerHTML = 0 +router.afterEach((to, from) => { + increment('afterEach') +}) + +Vue.use(VueRouter) + +let vueInstance +const mountEl = document.getElementById('mount') +const unmountEl = document.getElementById('unmount') + +mountEl.addEventListener('click', () => { + vueInstance = new Vue({ + router, + template: ` +
    +

    Hello "Restart-app"

    +
      +
    • Go to Home
    • +
    • Go to Foo
    • +
    + +
    + ` + }).$mount('#app') +}) + +unmountEl.addEventListener('click', () => { + vueInstance.$destroy() + vueInstance.$el.innerHTML = '' +}) diff --git a/examples/restart-app/index.html b/examples/restart-app/index.html new file mode 100644 index 000000000..c8885ad66 --- /dev/null +++ b/examples/restart-app/index.html @@ -0,0 +1,21 @@ + + +← Examples index + +
    + + + + +
    + +Count beforeEach:
    +Count beforeResolve:
    +Count afterEach:
    + +
    + +
    + + + \ No newline at end of file diff --git a/test/e2e/specs/restart-app.js b/test/e2e/specs/restart-app.js new file mode 100644 index 000000000..0dca5c3b8 --- /dev/null +++ b/test/e2e/specs/restart-app.js @@ -0,0 +1,45 @@ +const bsStatus = require('../browserstack-send-status') + +module.exports = { + ...bsStatus(), + + '@tags': ['history'], + + basic: function (browser) { + browser + .url('http://localhost:8080/restart-app/') + .waitForElementVisible('#mount', 1000) + .assert.containsText('#beforeEach', '0') + .assert.containsText('#beforeResolve', '0') + .assert.containsText('#afterEach', '0') + + // Mounting will trigger hooks + .click('#mount') + .waitForElementVisible('#app > *', 1000) + .assert.containsText('#beforeEach', '1') + .assert.containsText('#beforeResolve', '1') + .assert.containsText('#afterEach', '1') + .assert.containsText('#view', 'home') + + // Navigate to foo route will trigger hooks + .click('#app li:nth-child(2) a') + .assert.containsText('#beforeEach', '2') + .assert.containsText('#beforeResolve', '2') + .assert.containsText('#afterEach', '2') + .assert.containsText('#view', 'foo') + + // Unmount + .click('#unmount') + .assert.containsText('#app', '') + + // Second mounting will trigger hooks + .click('#mount') + .waitForElementVisible('#app > *', 1000) + .assert.containsText('#beforeEach', '3') + .assert.containsText('#beforeResolve', '3') + .assert.containsText('#afterEach', '3') + .assert.containsText('#view', 'foo') + + .end() + } +} From cac3e2c1d232ec725f38b9013107e31924879b50 Mon Sep 17 00:00:00 2001 From: Volodymyr Makukha Date: Mon, 17 Aug 2020 19:58:28 +0300 Subject: [PATCH 3/4] refactor: split History.teardown method --- src/history/base.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/history/base.js b/src/history/base.js index 367c0bad5..f219c4acb 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -252,17 +252,25 @@ export class History { // Default implementation is empty } - teardown () { + teardownListeners () { // clean up event listeners // https://github.com/vuejs/vue-router/issues/2341 this.listeners.forEach(cleanupListener => { cleanupListener() }) this.listeners = [] + } + resetHistoryState () { // reset current history route // https://github.com/vuejs/vue-router/issues/3294 this.current = START + this.pending = null + } + + teardown () { + this.teardownListeners() + this.resetHistoryState() } } From b95e6702c75f5c85c6d4ef6b82e84f42df05c6ba Mon Sep 17 00:00:00 2001 From: Volodymyr Makukha Date: Wed, 26 Aug 2020 11:54:20 +0300 Subject: [PATCH 4/4] refactor: general History.teardown method --- src/history/base.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/history/base.js b/src/history/base.js index f219c4acb..3397e8709 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -252,26 +252,19 @@ export class History { // Default implementation is empty } - teardownListeners () { + teardown () { // clean up event listeners // https://github.com/vuejs/vue-router/issues/2341 this.listeners.forEach(cleanupListener => { cleanupListener() }) this.listeners = [] - } - resetHistoryState () { // reset current history route // https://github.com/vuejs/vue-router/issues/3294 this.current = START this.pending = null } - - teardown () { - this.teardownListeners() - this.resetHistoryState() - } } function normalizeBase (base: ?string): string {