exports.sync = function (store, router, options) { var moduleName = (options || {}).moduleName || 'route' store.registerModule(moduleName, { namespaced: true, state: cloneRoute(router.currentRoute), mutations: { 'ROUTE_CHANGED': function ROUTE_CHANGED (state, transition) { store.state[moduleName] = cloneRoute(transition.to, transition.from) } } }) var isTimeTraveling = false var currentPath // sync router on store change var storeUnwatch = store.watch( function (state) { return state[moduleName]; }, function (route) { var fullPath = route.fullPath; if (fullPath === currentPath) { return } if (currentPath != null) { isTimeTraveling = true router.push(route) } currentPath = fullPath }, { sync: true } ) // sync store on router navigation var afterEachUnHook = router.afterEach(function (to, from) { if (isTimeTraveling) { isTimeTraveling = false return } currentPath = to.fullPath store.commit(moduleName + '/ROUTE_CHANGED', { to: to, from: from }) }) return function unsync () { // On unsync, remove router hook if (afterEachUnHook != null) { afterEachUnHook() } // On unsync, remove store watch if (storeUnwatch != null) { storeUnwatch() } // On unsync, unregister Module with store store.unregisterModule(moduleName) } } function cloneRoute (to, from) { var clone = { name: to.name, path: to.path, hash: to.hash, query: to.query, params: to.params, fullPath: to.fullPath, meta: to.meta } if (from) { clone.from = cloneRoute(from) } return Object.freeze(clone) }