-
Notifications
You must be signed in to change notification settings - Fork 126
Provide a way to un-sync #64
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
Comments
Any update/comments/thoughts from the maintainers? |
Hey, sorry for not responding, it seems this issue slipped most people's radar - this repo is generally nor very active since it's a simple lib. Your issue raises a valid concern. I guess the possibility of an app that uses vuex, vue-router and vuex-router-sync being destryoed and rebuilt wasn't taken into account. My idea to solve this would be the following: Both const unsync = sync(store, router)
// ... later:
unsync()
// when re-starting the app, call `sync()` again. |
@LinusBorg Thanks for the reply! Yes, one of the things I like most about the Vue ecosystem is that most plugins/mixins are often 200 lines of code or less. I contemplated forking this project but figure it would be better to try to get this "fix" added into the official project. Depending on your workload, I am ok submitting a PR if that would help get this capability into production sooner. Please let me know! Thanks! |
@LinusBorg Yep agreed! Perhaps add a unit test or test case as well? I can do the PR later Today and submit the request. |
A Test case would of course be required, as would be a mention in the README of this repo. |
…vuejs#64) Currently, vuex-router-sync only publicly exposes a single method: ‘sync’. This method creates a store.watch as well as a router.beforeHook. No publicly available method existed to effectively ‘unsync’ vuex-router-sync and remove the watch and hook, which created ‘dangling’ refrences and a potential memory leak. Users of this library may need an ‘unsync’ function if they, for example, only use Vue.js in specific portions of their webapp (e.g. with React, Angular, etc.) and when users navigate away from that portion they want to remove/clean-up all Vue.js resources and components. Includes a unit test. Had to bump vue-router to version 2.5.0 which was the first version to allow de-registering hook functions.
@LinusBorg Sorry for the delay. Added a pull request. Regarding testing, I wasn't sure exactly how best to test the registration/de-registration of the store, router, and moduleName. I accessed some internal/private Vuex store properties (but these could obviously change as Vuex gets updated and break the tests). If you have a better or more clever way, I'm open to suggestions (or just remove those assertions). |
Currently, vuex-router-sync only publicly exposes a single method: ‘sync’. This method creates a store.watch as well as a router.beforeHook. No publicly available method existed to effectively ‘unsync’ vuex-router-sync and remove the watch and hook, which created ‘dangling’ refrences and a potential memory leak. Users of this library may need an ‘unsync’ function if they, for example, only use Vue.js in specific portions of their webapp (e.g. with React, Angular, etc.) and when users navigate away from that portion they want to remove/clean-up all Vue.js resources and components. Includes a unit test. Had to bump vue-router to version 2.5.0 which was the first version to allow de-registering hook functions.
Long story short: We're migrating our app from Angular 1 to Vue.js. To do that, we're building new "views" in Vue.js and hooking them into our Angular 1 app.
When our user navigates away from the portion of our app where a Vue.js root component was mounted, we destroy the Vue component:
Our vueApp is built in an Angular 1 component constructor and successfully mounted to the DOM.
Everything works as expected except when the user navigates away from this part of our app and then returns, a nasty exception gets thrown in
vue-router-sync
because the originalstore.watch
(https://github.com/vuejs/vuex-router-sync/blob/master/index.js#L18) is never cleaned up when thevueApp.$destroy
method is called (I'm assuming b/cvue-router-sync
still retains a reference to the store).Here is the error message:
Since the original store (the first time our component/Vue) is loaded is not destroyed when the user navigates away from our component, the watch triggers again when the user returns to the component and if
route.fullPath
is different than the previouscurrentPath
variable, then it thinks TimeTraveling is occurring, that the Vuex state has changed, and tries to replace the current route.So my "issue/bug" is that I assume
vuex-router-sync
was written without the idea that someone would try to destroy the root Vue component. Is it possible to register a watch handler whenscope.watch
is called and then export adesync
method or some way to allow the developer to "unwatch" the Vuex state.I found this on Vuex Github: vuejs/vuex#599
It sounds like Vuex won't naturally clean up watch elements and they should be manually
unwatch
ed but this plugin doesn't provide a method to do that.Follow-up:
It looks like this project also hooks into
router.afterEach
. Again, if there's no way to "unhook" this event registration, won't this plugin leak each timesync(store, router)
is called with a newVuex
andVueRouter
object?I recognize we could not destroy our root Vue component when the user navigates away from our Angular 1 component or we could create a global Vuex state for the entire application and never destroy it, but while we "upgrade-in-place" it makes it more efficient, performant, and modular to destroy root Vue components when a user navigates back to a legacy part of our Angular 1 application.
The text was updated successfully, but these errors were encountered: