Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove all beforeEach, afterEach, beforeResolve #2341

Closed
mistersender opened this issue Aug 6, 2018 · 3 comments · Fixed by #3172
Closed

Remove all beforeEach, afterEach, beforeResolve #2341

mistersender opened this issue Aug 6, 2018 · 3 comments · Fixed by #3172
Labels
feature request micro frontends Features to handle micro frontends
Projects

Comments

@mistersender
Copy link

mistersender commented Aug 6, 2018

Version

3.0.1

Reproduction link

https://jsfiddle.net/se6gLaqn/1/

Steps to reproduce

Create a vue instance, as well as a router instance. Then destroy the vue instance.

The router instance continues to exist and fire.

What is expected?

The router should be able to properly destroy itself; either by explicit call, or when the vue instance is destroyed

What is actually happening?

The router exists and cannot be destroyed


I did some googling and see that vue-router cannot currently be destroyed, but I am asking for reconsideration. Unlike the other issue I found (#954) where it appeared the user wanted to destroy and create a new router in the same application, the issue I am having is completely separate.

I have a massive application that essentially uses pjax methodologies to be able to run several SPAs (vue being one) that create the full site. When we navigate away from one SPA to another, the SPA needs to destroy itself so it's code does not interfere with the other SPAs. However, because the vue router cannot be destroyed; it's attempting to execute logic for routing even when the SPA that created it is destroyed. The issue compounds when we have more than 1 vue application running, as there are now 2 instances of vue-router (or more) running at a time.

Specifically, we are using the hash version of routing. It looks like the router just attaches an event to the window and listens for popstates, but things get weird when more than one event does something with popstate (an understandably oddball behavior). I would appreciate reconsideration for allowing vue-router to destroy itself when appropriate. Thanks!

[edited for spelling/grammar]

@matthew-white
Copy link

I'm also interested in this functionality. Looking at #1102, I see that a single router can be injected into multiple Vue instances: router.apps is the array of those instances. I wonder if something like the following would be possible:

  • When a Vue instance is destroyed, it asks the router to remove it from router.apps.
  • If router.apps becomes empty:
    • router.app becomes null.
    • The router asks its history instance to remove its listeners.
  • If the router is then injected into a new Vue instance:
    • router.app is set to that instance.
    • The router asks its history instance to set up listeners again.

If something like that were in place, I think it'd be possible for multiple routers to coexist as long as only one of them at a time has been injected into a non-destroyed Vue instance.

@posva posva added this to Long term road (high prio, low complex) in Longterm Mar 26, 2019
@posva posva changed the title vue-router does not destroy itself Remove all beforeEach, afterEach, beforeResolve Apr 11, 2019
@posva
Copy link
Member

posva commented Apr 11, 2019

After looking at other issues like #2639, we cannot just remove all listeners from the router. We can however unset router.app.

Currently, you have to keep the returned value from beforeEach, which is a function you can call to unsubscribe later:

const stop = router.beforeEach((to, from, next) => {
  let rte =  document.getElementById('someMessage')
console.log(to)
  rte.innerText = `Router Path: ${to.path}`
  next()
})

let vm = new Vue({
	router,
  el: '#app',
  data: {
    msg: 'Hello World'
  }
})

setTimeout(() => {
  console.log("about to destroy")
let dest =  document.getElementById('destroyed')
	dest.innerText = `vm.destroy() called, vue is dead. but the router still works. booo`
  vm.$destroy()
  stop()
}, 10000)

I'm changing this into a feature request to remove all listeners

@posva posva moved this from Long term road (high prio, low complex) to Ignore for now (low prio, high complex) in Longterm Apr 11, 2019
@joeldenning
Copy link
Contributor

I have put together a fix for this at #3172

posva pushed a commit that referenced this issue May 19, 2020
…3172)

* feat(history): Remove event listeners when all apps are destroyed.

* fix(tests): Adding test assertions

* fix(feedback): addressing @posva's feedback

* fix(index): posva's feedback

* feat(tests): adding multi-app test

* fix(feedback): posva's feedback

* fix(feedback): unmounting apps with buttons outside of the app

Close #3152
Close #2341
@posva posva moved this from Ignore for now (low prio, high complex) to Done in Longterm May 26, 2020
@posva posva added the micro frontends Features to handle micro frontends label Aug 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request micro frontends Features to handle micro frontends
Projects
Development

Successfully merging a pull request may close this issue.

4 participants