Giter Club home page Giter Club logo

vuex-router-sync's Introduction

Vuex Router Sync

npm ci status coverage license

Sync Vue Router's current $route as part of Vuex store's state.

中文版本 (Chinese Version)

Usage

# the latest version works only with vue-router >= 2.0
npm install vuex-router-sync

# for usage with vue-router < 2.0:
npm install vuex-router-sync@2
import { sync } from 'vuex-router-sync'
import store from './store' // vuex store instance
import router from './router' // vue-router instance

const unsync = sync(store, router) // done. Returns an unsync callback fn

// bootstrap your app...

// During app/Vue teardown (e.g., you only use Vue.js in a portion of your app
// and you navigate away from that portion and want to release/destroy
// Vue components/resources)
unsync() // Unsyncs store from router

You can optionally set a custom vuex module name:

sync(store, router, { moduleName: 'RouteModule' } )

How does it work?

  • It adds a route module into the store, which contains the state representing the current route:

    store.state.route.path   // current path (string)
    store.state.route.params // current params (object)
    store.state.route.query  // current query (object)
  • When the router navigates to a new route, the store's state is updated.

  • store.state.route is immutable, because it is derived state from the URL, which is the source of truth. You should not attempt to trigger navigations by mutating the route object. Instead, just call $router.push() or $router.go(). Note that you can do $router.push({ query: {...}}) to update the query string on the current path.

License

MIT

vuex-router-sync's People

Contributors

blake-newman avatar cgarnier avatar dujuncheng avatar jounqin avatar kazupon avatar kiaking avatar mehwww avatar neverbehave avatar nkoterba avatar pixelgrid avatar predhme avatar ryutamaki avatar scottbedard avatar snaptopixel avatar vinicius73 avatar yyx990803 avatar zigomir avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vuex-router-sync's Issues

Uncaught TypeError: store.registerModule is not a function

index.js?0d67:4 Uncaught TypeError: store.registerModule is not a function
    at exports.sync (eval at <anonymous> (app.js:874), <anonymous>:6:9)
    at eval (eval at <anonymous> (app.js:776), <anonymous>:28:26)
    at Object.<anonymous> (app.js:776)
    at __webpack_require__ (app.js:660)
    at fn (app.js:84)
    at Object.<anonymous> (app.js:966)
    at __webpack_require__ (app.js:660)
    at app.js:709
    at app.js:712

webpack2 + vue/vuex

store.js:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = {
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
};

export default store;

main.js:

import Vue from 'vue';
import { sync } from 'vuex-router-sync';
import App from './App';
import store from './store';
import router from './router';

sync(store, router);
const app = new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App }
});

export { app, router, store };

vuex-router-sync@next as default

The next versions of vue-router and vuex was released as default, so i think vuex-router-sync@next should be released as default.

Extra history change make browser native back/forward don't work correctly

I have a use case which use Vue as PHP -- just use its ssr feature to render pages. I notice that browser native back/forward don't work correctly cause of this will push a needless extra history change on each init render, which make the native back button must be click twice to back last page.

I made a pr about this issue.

Browser back not updating Store

I am updating the url on a page with router.push to append queries to the url. After each router.push the store data is updated. When I click the browser back button the store does not update to what it was before but the url does.

url changes from: /showcase
to /showcase?choice=1

router.push({ path: '/showcase', query: query});
axios.get('/urlcall', {
          params: query
        })
        .then(function (response) {
          store.commit('updateStore', response.data);
        })
        .catch(function (error) {
          console.log(error);
        });
    },

What is the solution?

Passing a string array containing the name of mapped state properties to mapState doesn't work

Without vuex-router-sync, the following two ways both works in child component and are equivalent:
mapState({ prop: state => state.prop })
and
mapState([ 'prop' ]).
But they don't work when using vuex-router-sync.

Instead, I found the following works:
mapState({ prop: state => state.Schema.prop })

Where does this Schema come from? It is only accessible in child component but not in the root store js file.

v4.0.1 production lib contains keywords 'const'

line 42

function cloneRoute (to, from) {
  const 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)
}
```

how to make router redirect to login when the auth state is kept by store?

I want store to keep the state of auth or user info, also keep auth state in cookie or localstorage.
when user open the page, try to get the auth from cookie or localstorage and make it into store.
and make router redirect to login when user not login or can not get auth locally.
should I do that within router.beforeEach? but how could I get the store.state.auth

any advice?

$router.push doesn't change the URL

router.push and this.$router.push does not changes the URL when using vuex-router-sync.

<router-link> works as expected.

When I remove vuex-router-sync router.push works as expected.

// current url #/foo
this.$router.push({path: 'bar'})
// expects URL to be #/bar
// actual URL is still #/foo

Uncaught TypeError: Cannot read property 'path' of undefined

"vue": "^2.0.1",
"vue-router": "^2.0.0",
"vuex": "^2.0.0",
"vuex-router-sync": "^3.0.0"

routes

const routes = [
  {
    path: '/',
    component: Home
  },
  {
    path: '/about',
    component: About
  }
]

has error

import { sync } from 'vuex-router-sync'
import router from './router'
import store from './store'

sync(store, router)

no error

// import { sync } from 'vuex-router-sync'
import router from './router'
import store from './store'

// sync(store, router)

Route params is empty when reloading on the path

Steps to Reproduce

  • Create a getter named route function return state.route
  • The render it on a component using mapGetters(['route'])

What is expected

Route Params must have properties

###What happened

Route params is empty

How to update route state with own mutation, action and splited store?

Hi,

first of all big thanks for such great framework :).

I'm building data-table-grid like app, and I have some basic sort of "filtering" functionality with text inputs, and I want to sync it's values with query params in route? If someone change query param value it should update input text filter for that, and on the other hand if I update the input it should save it's updated state in the query param.

How to achieve that?

I'm playing with https://github.com/skyronic/vue-spa example app which has splited modules like cart and products, but vuex-router-sync adds its own route module... I dont know how can I supply my "route store" with my own "actions" and "mutations" for update that filter state in change in url and "getters"

There is so many files in that project, I want to provide a live example for you with, but in http://www.webpackbin.com/ I have so errors with file paths...

store.route doesn't contain the `matched` property

I noticed that the matched property doesn't exist on the cloned route that gets sent to the store.

I wanted to create a getter that basically merges all the meta fields, so I can access if from the templates:

export function meta (state) {
  return state.route.matched.reduce((prev, match) => {
    return Object.assign({}, prev, match.meta)
  }, {})
}

At the moment, it doesn't work. Could this be added, or are there reasons for the current behaviour?

A little bit related to #31.

Missing url update for state.route.params and state.route.query changes

Hi,

the URL change is reactive only when state.route.path has changed, but for route.param or query does not.

main.js

import App from './pages/App'
import router from './router'
import store from './vuex/store' // vuex store instance
import { sync } from 'vuex-router-sync'

sync(store, router)

router.start(App, '#app')

pages/App.vue

<template>
<div class="app">
  <div class="header">
  </div>
  <div class="page">
    <router-view></router-view>
  </div>
</div>
</template>

<script>
  import store from '../vuex/store'
  export default {
    store
  }
</script>

pages/HomePage.vue

<template>
  <input type="text" :value="getFilter" @input="updateFilter">
</template>

<script type="text/babel">
  import { updateFilter } from '../vuex/actions'
  import { getFilter } from '../vuex/getters'

  export default {
    vuex: {
      getters: {
        getFilter
      },
      actions: {
        updateFilter
      }
    }
  }
</script>

router.js

import HomePage from './pages/HomePage'
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)
var router = new VueRouter({
  history: false
})

router.map({
  '/': {
    component: HomePage
  }
})

export default router

vuex/store.js

import Vue from 'vue'
import Vuex from 'vuex'
import createLogger from 'vuex/logger'
import * as types from '../vuex/mutation-types'

Vue.use(Vuex)
Vue.config.debug = true

const debug = process.env.NODE_ENV !== 'production'

const state = {
}

const mutations = {
  [types.UPDATE_FILTER] (state, value) {
    state.route.query['filter'] = value
  }
}

export default new Vuex.Store({
  state,
  mutations,
  strict: debug,
  middlewares: debug ? [createLogger()] : []
})

vuex/actions.js

import * as types from '../vuex/mutation-types'

export const updateFilter = function ({ dispatch, state }, e) {
  dispatch(types.UPDATE_FILTER, e.target.value)
}

vuex/getters.js

export function getFilter (state) {
  return state.route.query.filter
}

vuex/mutation-types.js

export const UPDATE_FILTER = 'UPDATE_FILTER'

Cannot read property 'route' of undefined

When I use vuex-router-sync, but something wrong happened

import { sync } from 'vuex-router-sync'
import router from './router'
import store from './store'
sync(store, router)

error message

Uncaught TypeError: Cannot read property 'route' of undefined            index.js:23

dependencies

    "vue": "^2.0.1",
    "vue-router": "2.0.0-rc.5",
    "vuex": "^2.0.0",
    "vuex-router-sync": "^3.0.0"

currentPath should has a init value

currentPath is undefined

server Rending ...
store.replaceState(window.INITIAL_STATE)

since currentPath is undefined , so router.push(route) must be excute. the history must has two record

Peer [email protected] wants vuex@>= 0.6.2 < 3

$ npm install --save vuex-router-sync
npm WARN peerDependencies The peer dependency vuex@>= 0.6.2 < 3 included from vuex-router-sync will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency 
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.
npm ERR! Linux 4.4.0-36-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "install" "--save" "vuex-router-sync"
npm ERR! node v4.5.0
npm ERR! npm  v2.15.9
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package [email protected] does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants vuex@>= 0.6.2 < 3

npm ERR! Please include the following file with any support request:
npm ERR!     /home/ferri/Developments/domains/d2/npm-debug.log

Hi i've got error like that when try to run npm install --save vuex-router-synx. Any idea? this is my package.json

"dependencies": {
    "babel-runtime": "^6.0.0",
    "vue": "^1.0.21",
    "vue-router": "^0.7.13",
    "vuex": "^1.0.0-rc.2"
  },

Thanks

Hold a reference to the router object?

I have a need to redirect the user after a store action, but the store doesn't have access to the router object itself.

I forked it locally and added a reference in the store.registerModule:

  store.registerModule('route', {
    state: {},
    mutations: {
      'router/ROUTE_CHANGED': function (state, to) {
        store.state.route = Object.freeze({
          name: to.name,
          path: to.path,
          hash: to.hash,
          query: to.query,
          params: to.params,
          fullPath: to.fullPath,
          router: router
        })
      }
    }
  })

Can this be made official? Or is there a good reason not to be have access to the router in the store that I'm not aware of?

Redirect in action

I'm sorry if I'm missing something but I'm really lost for last few hours.

I'm using vuex+vue-router-sync and I want to redirect after successfull action. My code look like this:

import * as types from './mutation-types'
import { AuthResource } from '../api/index.js'

export const logInUser = ({commit}, user) => {
  AuthResource.logInUser(user).then((data, error) => {
    commit(types.SET_ACCESS_TOKEN, data.body)
    $router.go({path: '/app'})
  }).catch((err) => {
    commit(types.SHOW_MSG, {content: err.body.error_description, title: 'Whoops!', type: 1})
  })
}

But I'm unable to get It working. I still get $router undefined.

Feature request: deep state sync option

Hi,

I'm having a hard time to solve this very simple problem: "If the user is navigation back and/or forth using builtin history action (aka history button) I want to give him back the exact same state he was at the time".

I've noticed this plugin is not for synchronizing the store state with the router state but rather gives from the store access to the router current info (state?). Btw the name is confusing to me since it doesn't sync.

Thank you in advance!

newly added module properties aren't reactive

I understand the need for immutability expressed here by cloning then freezing the route object,
but it prevents Vue from making the properties observable, which means getters depending on the route module state are not cached like standard computed properties and recompute every time the route object changes, even if some properties (params, query) stay the same.

I resolved this in my project by making my own sync module which diffs the old route object with the new one, but I assume this may be a concern for more people in the future.

Throws "Cannot read property 'getters' of undefined" using vuex's dynamic modules

Issue

When I activate the sync I get the following error:

vuex.js?90cb:123 Uncaught TypeError: Cannot read property 'getters' of undefined
    at Vue$3.mappedGetter (eval at <anonymous> (app.js:825), <anonymous>:123:31)
    at Watcher.get (eval at <anonymous> (app.js:658), <anonymous>:2936:27)
    at Watcher.evaluate (eval at <anonymous> (app.js:658), <anonymous>:3044:21)
    at Proxy.computedGetter (eval at <anonymous> (app.js:658), <anonymous>:3240:15)
    at n (backend.js:1)
    at n (backend.js:1)
    at n (backend.js:1)
    at n (backend.js:1)
    at n (backend.js:1)
    at n (backend.js:1)

Use Case

I have an app composed by two distinct areas, for simplicity lets say that we have the following routes:

mode: 'history',
[
 {
   name: 'area1',
   path: '/area1',
   component: resolve => require(['./views/area1'], resolve)
 },
 {
   name: 'area2',
   path: '/area2',
   component: resolve => require(['./views/area2'], resolve)
 },
]

I have a global store being registered that looks like this:

export default {
  state: {
    user_id: ''
  },
  getters: {
    USER_ID_GET: ({ user_id }) => user_id
  },
  actions: {
    USER_ID_SET: ({ commit }, payload) => {
      commit('USER_ID_SET', payload)
    }
  },
  mutations: {
    USER_ID_SET: (state, payload) => {
      state.user_id = payload
    }
  }
}

And then I have two dynamic stores each one being registered/unregistered when either area1 or area2 components are created/destroyed. This is an example for area1:

// store1.js
export default {
  state: {
    ids: []
  },
  getters: {
    IDS_GET: ({ ids }) => ids
  },
  actions: {
    IDS_ADD: ({ commit }, payload) => {
      commit('IDS_ADD', payload)
    },
    IDS_RESET: ({ commit }) => {
      commit('IDS_RESET')
    }
  },
  mutations: {
    IDS_ADD: (state, payload) => {
      state.ids.push(payload)
    },
    IDS_RESET: (state) => {
      state.ids = []
    }
  }
}
// area1.vue
<template>
  <div>
    <router-link :to="{ name: 'area2' }">Go To Area 2</router-link>
  </div>
</template>
<script>
  import store from './store1'
  export default {
    beforeCreate () {
      this.$store.registerModule('area1Module', store)
    },
    beforeDestroy () {
      this.$store.unregisterModule('area1Module')
    }
  }
</script>

So if I click the link defined in the template I get always the error mentioned at the beginning of the post but if I comment sync(store, router) everything works fine.

Compatibility with versions of vuex and vue-router

The README doesn't say what versions of vuex and vue-router different versions of this plugin is compatible with: it would be great if it could!


Old issue:

Hey!

Is it possible to use vuex 1 with vue-router 2? vuex-router-sync@2 doesn't seem compatible with vue-router 2, while 3 and 4 aren't compatible with vuex 1.

This kind of sucks given that the migration guide literally said I wouldn't have to update vuex. I'd suggest that if you have to update vuex to use vue-router 2 than the docs should be changed to say that yes, you do have to update vuex. https://vuejs.org/v2/guide/migration.html#FAQ

Performance with vuex `encode`

Noticing a reported click delay in console, I tried to get a flame chart of the click actions. The result shows that it takes most of its time in a vuex encode method. When I tried to debug, it is encoding the router object, which has some deeply nested components structure like data.from.matched[0].instances.default.$children[0].$children[0].$children[0]...... I haven't dived into what encode is doing but wonder if it is necessary?

vuex-router-sync-encode

vuex-router-sync-encode-debug

Updating the route state after full page refresh

Hello, I'm not quite sure if it's caused by misconfiguration on my part (vue webpack template + vue-router + sync), but the router/ROUTE_CHANGED mutation is not being called after a full page refresh, resulting in empty route state causing issues when used in combination with derived state. It behaves as expected when browsing the page states afterwards.

Thanks!

Uncaught TypeError: store.registerModule is not a function

I just create a new project from vue-cli. And I get this error when try to add vuex-router-sync

index.js?7e73:4 Uncaught TypeError: store.registerModule is not a function
    at exports.sync (eval at <anonymous> (app.js:2927), <anonymous>:4:9)
    at eval (eval at <anonymous> (app.js:1512), <anonymous>:23:26)
    at Object.<anonymous> (app.js:1512)
    at __webpack_require__ (app.js:660)
    at fn (app.js:86)
    at Object.<anonymous> (app.js:2966)
    at __webpack_require__ (app.js:660)
    at app.js:709
    at app.js:712

main.js

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import { sync } from 'vuex-router-sync'

sync(store, router, { moduleName: 'RouteModule' })

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App }
})

store

import Vuex from 'vuex'
import Vue from 'vue'
import home from './home.js'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    home
  }
})

export default {
  store
}

Can not install from npm

Hi, when I'm trying to add vuex-router-sync to the project I'm getting this error:

npm ERR! Darwin 15.4.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "vuex-router-sync" "--save-dev"
npm ERR! node v4.1.1
npm ERR! npm  v2.14.4
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package [email protected] does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants babel-runtime@^6.0.0

Route name in store

Isn't it a good idea to also store the name of the current route (if one exists) in the store as well? I'll be happy to make a PR

If it's the same component timetravel is not set to true

Hi !

I try to make this sync work in my project.
i use this for multi-language:

        '/': { name: 'home-en', component: Home, lang: 'en' }, 
        '/about': { name: 'about-en', component: About, lang: 'en' }, 

        '/accueil': { name: 'home-fr', component: Home, lang: 'fr' }, 
        '/a-propos': { name: 'about-fr', component: About, lang: 'fr' }, 

If i change the route from home to about, everything is fine.

But the first time if i try to change from 'about' to 'a-propos' nothing append.

If i try to change from one language to another, the url change a lot of time and stop....

I thing it's because, if it's the same component, he never enter on the route.afterEach, because timetravel is set to true...

Anyway, thanks for this example :)

need fetch "from" state not just the "to" state

i think it's necessary to add get from state info like beforeRouteEnter (from,to,next) now we can fetch the to state by store.route but some times to a view we must decide wether or not load data by the from state's path.
i.e. go to a product-details view from product-list view need loading details info and in that product-details view go to anther order view and back ,some contents managed by vuex had changed,so in details view i don't want load data because not necessary)

Provide a way to un-sync

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:

// ($onDestroy is angular component destroy hook)
  $onDestroy() {
    console.log('DESTROYING VUE')
    this.vueApp.$destroy();
  }

Our vueApp is built in an Angular 1 component constructor and successfully mounted to the DOM.

import Vue from 'vue'
import { sync } from 'vuex-router-sync'

import store from '../store'
import router from '../router'

import Main from '../Main.vue'

class BootstrapReportsController {
  constructor () {
    sync(store, router)

    this.vueApp = new Vue({
      router,
      store,
      ...Main
    }).$mount('#reports')
  }

  $onDestroy() {
    console.log('DESTROYING VUE')
    this.vueApp.$destroy();
  }
}

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 original store.watch (https://github.com/vuejs/vuex-router-sync/blob/master/index.js#L18) is never cleaned up when the vueApp.$destroy method is called (I'm assuming b/c vue-router-sync still retains a reference to the store).

Here is the error message:

lib_bundle.js:246653 [Vue warn]: Error in callback for watcher "function () { return getter(this$1.state, this$1.getters); }": "TypeError: Cannot assign to read only property 'path' of object '#<Object>'"

(found in <Root>)
warn @ lib_bundle.js:246653
handleError @ lib_bundle.js:246736
run @ lib_bundle.js:249148
update @ lib_bundle.js:249120
notify @ lib_bundle.js:246952
reactiveSetter @ lib_bundle.js:247174
ROUTE_CHANGED @ defense_all.js:123
wrappedMutationHandler @ lib_bundle.js:254206
commitIterator @ lib_bundle.js:253930

lib_bundle.js:246740 TypeError: Cannot assign to read only property 'path' of object '#<Object>'
    at Object.match (lib_bundle.js:244995)
    at VueRouter.match (lib_bundle.js:246014)
    at AbstractHistory.transitionTo (lib_bundle.js:245466)
    at AbstractHistory.push (lib_bundle.js:245925)
    at VueRouter.push (lib_bundle.js:246082)
    at Vue$3.store.watch.sync (defense_all.js:145)
    at Watcher.run (lib_bundle.js:249146)
    at Watcher.update (lib_bundle.js:249120)
    at Dep.notify (lib_bundle.js:246952)
    at Object.reactiveSetter [as route] (lib_bundle.js:247174)

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 previous currentPath 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 when scope.watch is called and then export a desync 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 unwatched 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 time sync(store, router) is called with a new Vuex and VueRouter 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.

Create actions to expose router methods

Can we consider adding some vuex actions for the following methods:

  • Push
  • Replace
  • Go

Right now, it's a little awkward in that we can access the state from Vuex using this plugin, but you are still required to interact with the router via direct access.

With this proposal, I want the flow to look something akin to this (which I believe is how integrations between react-router and redux generally function):

image

Incompatable with vuex 0.8.0

I have recently updated my application to use vuex 0.8.0 which seems to cause infinite redirects when used in conjunction with router-sync.

a question of `vuex-router-sync`

I don't know much about the usage scenario of vuex-router-sync. What problem is it mainly used to solve? ( In other words, after using the router in vuex, you can solve a problem very easy )

我不太清楚 vuex-router-sync 的应用场景。它主要是用来解决什么问题。(换句话说,在使用了 router in vuex 之后,可以很好的解决某类问题)。

thx.
谢谢

使用vuex-router-sync后,在beforeResolve中调用vuex里registerModule会再次触发beforeResolve回调

使用vuex-router-sync后,在beforeResolve中调用vuex里registerModule会再次触发beforeResolve回调,结果导致页面数据读取两次。
//package.json
"vue": "^2.2.1",
"vue-router": "^2.5.3",
"vuex": "^2.3.1",
"vuex-router-sync": "^4.1.3"
//js
router.beforeResolve((to, from, next) => {
store.registerModule("test" , {});
console.log(to)
next();
});
//console
Object { name: undefined, meta: Object, path: "/home", hash: "", query: Object, params: Object, fullPath: "/home", matched: Array[1], redirectedFrom: "/" }
Object { name: undefined, meta: Object, path: "/home", hash: "", query: Object, params: Object, fullPath: "/home", matched: Array[1] }

How to access `store` in beforeEnter

How access store in beforeEnter ?

// main.js
import store from './store'
import router from './router'
import { sync } from 'vuex-router-sync'

sync(store, router)
// routes.js
function requireAuth (to, from, next) {
  if (!store.getters.isAuthenticated) { /// THIS NOT WORK, HOW TO ACCESS STORE?
    window.location.href = '/auth/v1/auth0/connect'
  } else {
    next()
  }
}

export default [
  {
    path: '/', component: Timeline
  },

  {
    path: '/events',
    component: Events,
    beforeEnter: requireAuth
  }
]

Don't use `router.replace` or `router.push` on initialization render (SSR related)

There was an original issue #59 described about it, but its fix #52 caused another problem for browsers which do not support history API or redirecting from server like vue-hacknews-2.0:

vue-hn now redirects from / to /top on server.

  1. When we do not use fallback: false and visit /, /top or /new, it will fallback to HashHistory then call location.replace('/#'+ hash), then it will redirect to / again, then redirecting to /top... It causes vuejs/vue-hackernews-2.0#218 , so we need to set fallback: false
  2. When we use fallback: false and visit /, /top or /new, it will use HTML5History and then on initialization render currentPath is undefined, so router.replace will be called, but IE9 does not support history API so it will reload /top or /new, etc... It causes vuejs/vue-hackernews-2.0#221

`transition.to` isnt set on initial route

in router.afterEach the property to isnt defined on transition

    "vue": "^2.0.0-beta.5",
    "vue-router": "^2.0.0-beta.4",
    "vuex": "^2.0.0-rc.3",
    "vuex-router-sync": "^2.0.2",

hotUpdate to add `router/ROUTE_CHANGED` removes all other modules

i worked around it by copying the index.js into my project and changing the hotUpdate to

var modules = store._modules
modules.route = {
  mutations: {
    'router/ROUTE_CHANGED': function (state, to) {
      state.path = to.path
      state.query = to.query
      state.params = to.params
    }
  }
}
store.hotUpdate({
  modules: modules
})

Accessing routes in getters

const getters = {
  getParams: rootState => {
    return rootState.route.params
  },
}

The above doesn't work. How is this done?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.