GithubHelp home page GithubHelp logo

redux-vuex's Introduction

redux-vuex

Redux bindings for VueJS inspired by Vuex.

First things first

Why don't you use vuex instead?

Redux and vuex are really hard to compare. Vuex is a state management pattern that clearly defines each subject of the state lifecycle. For most of the projects this helps a lot structuring your application but it also leaves a large architectural footprint.

Redux on the other hand is very adaptable to different scenarios giving you the ability to customize everything around state management like handling side effects (see redux-effects, redux-saga or redux-thunk) or even adapting full application flows like rematch.

Yay, yet another redux lib for VueJS

Valid point, it seems the needs for integrating with redux is strong. So depending on your requirements you may want to use:

  • vuejs-redux if you want provider bindings like react-redux
  • vdeux if you want a different kind of component bindings
  • revue also for nice store bindings but unfortunately its dead :(

Installation

redux-vuex is written in pure es6 and only has dependencies to the beautiful crafted packages get-value and set-value

Get the Package

npm i redux-vuex@next // yarn add redux-vuex

Connect it to your Vue application

import { createApp } from 'vue'
import { provideStore } from 'redux-vuex'

import App from './App.vue'
import { store, actions } from './store'

const app = createApp(App)

provideStore({
  app,
  store,
  actions
})

app.mount('#app')

Usage

redux-vuex is focused on simplifying the access to the redux state and bind state changes to the vue instance in an efficient way.

mapState

To assign state with ease to your component mapState needs to be used. It has two different signatures, depending on your component needs:

Automatic

If you want a 1:1 relationship between your redux store's state property names and your vue component's data then pass the names of these properties from redux as string arguments to mapState:

import { mapState } from 'redux-vuex'

export default {
  name: 'My Vue Component',
  setup() {
    return mapState('users', 'todos') // maps state.users and state.todos to data.users and data.todos
  }
}

Custom property names

Alternatively, if you provide an object to mapState you can specify data property names.

import { mapState } from 'redux-vuex'

export default {
  name: 'My Vue Component',
  setup() {
    return mapState({
      users: 'users', // maps state.users to data.users
      todoList: 'todos' // maps state.todos to data.todoList
    })
  }
}

Single property

You can pass a function that has access to the state object if you want to

import { mapState } from 'redux-vuex'

export default {
  name: 'My Vue Component',
  setup() {
    return mapState({
      state: (state) => ({ todoList: state.todos, users: state.users }) // maps state.todos to data.state.todoList and state.users to data.state.users
    })
  }
}

You can use the last two methods together like so

import { mapState } from 'redux-vuex'

export default {
  name: 'My Vue Component',
  setup() {
    return mapState({
      users: 'users', // maps state.users to data.users
      todoList: (state) => state.todos // maps state.todos to data.todoList
    })
  }
}

Note: using the object notation gives you the ability to use store selectors.

mapActions

For a more convenient action dispatching mapActions can be used. To use this helper you need to pass in the actions in the connect function (see above):

const actions = {
  foo: payload => {
    type: 'FOO', payload
  },

  bar: () => {
    type: 'BAR', payload: { bar: 'baz' }
  }
}
import { mapActions } from 'redux-vuex'

export default {
  name: 'My Vue component',
  setup() {
    return mapActions('foo', 'bar') // creates scoped functions for foo and bar action
  }
  mounted() {
    this.foo('baz') // will dispatch { type: 'FOO', payload: 'baz' }
  }
}

If you need to dispatch multiple actions in one method (or want to assign different names), use the object notation:

import { mapActions } from 'redux-vuex'

export default {
  name: 'My Vue component',
  setup() {
     return mapActions({
        baz: ({ dispatch, actions }, arg1, arg2) => {
          dispatch(actions.foo(arg2))
          dispatch(actions.bar())
        }
     })
  }
  mounted() {
    this.baz('foo', 'bar') // will dispatch foo and bar actions
  }
}

store

Finally, if you need direct access to the store, each component has a binding to the store assigned:

import { inject } from 'vue'
import { injectStore, injectActions } from 'redux-vuex'

export default {
  name: 'My Vue component',
  setup() {
    const store = injectStore()
    const actions = injectActions()

    store.subscribe(() => {
      console.log(store.getState())
    })

    store.dispatch({
      type: 'foo',
      payload: 'bar'
    })
  }
}

Caveats

If you return more than the mapState from the setup make sure to bind the result to a dedicated property. Otherwise the Vue proxies won't work ๐Ÿ˜‘

import { mapState } from 'redux-vuex'

export default {
  name: 'My Vue Component',
  setup() {
    return {
      state: mapState({
        users: 'users', // maps state.users to data.users
        todoList: (state) => state.todos // maps state.todos to data.todoList
      }),
      ...mapActions('foo', 'bar')
    }
  }
}

How it works

  • provideStore provides the redux store for composable components
  • mapState creates a reference binding form the redux store
  • Each Vue Component with bindings creates a store subscription
  • On each state change all bindings are evaluated and update
  • Only the mapped properties are retrieved from store and setted

License

MIT

redux-vuex's People

Contributors

alexander-heimbuch avatar dv8fromtheworld avatar haritha2112 avatar herrmannplatz avatar letty avatar rbutera 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

Watchers

 avatar  avatar  avatar

redux-vuex's Issues

Usage of mapState with TypeScript in vue

I am trying to access a state variable using typescript. I am unable to get it to work. This is what I have so far.

<script type="ts">
interface Auth {
 accessToken?: string;
 expiresAt?: number;
 authenticated?: boolean;
}
import { mapState } from 'redux-vuex';
import { Vue, Component } from 'vue-property-decorator';
export default class Example extends Vue {
  private auth: Auth = mapState({
    auth: 'auth'
  })
}
</script>

When I try to access the auth variable using this.auth, I am being returned a function instead of the contents of the state object 'auth'. What is the right way of accessing this state variable if using typescript?

pre-bound this.mapState bug

Firstly, thanks for open-sourcing this library! Saved me a lot of headache!

There seems to be a small bug when trying to map an object with the pre-bound this.mapState function as shown in the README example:

export default {
  name: 'My Vue Component',
  data () {
    return {
      baz: 10
      ...this.mapState({
        baz: function (state) {
          return state.bar + this.baz //maps state.bar + 10 to data.baz
        }
      })
    }
  }
}

Namely, Vue complains that the value has not been defined and looking at the devtools, I can see that it has mapped an object as the object key:

screenshot 2018-10-08 at 13 01 23

At first glance, the rest parameters in mixin.js seems to be the culprit.

this.mapState = (...props) => mapState(props).call(this)

Replacing it with a simple props argument fixes the issue, although I haven't had the chance to look at how it actually affects the mapState function and if it has any side-effects.

Declaration files missing in v0.3.2 release

Hi alex~

I just tried the [email protected] and it feels like those declation files are missing

npm pack redux-vuex
npm notice 
npm notice ๐Ÿ“ฆ  [email protected]
npm notice === Tarball Contents === 
npm notice 463B   .editorconfig      
npm notice 7.5kB  dist/index.js      
npm notice 150B   src/index.js       
npm notice 1.2kB  src/map-actions.js 
npm notice 1.5kB  src/map-state.js   
npm notice 1.4kB  src/mixin.js       
npm notice 602B   webpack.config.js  
npm notice 829B   package.json       
npm notice 10.6kB dist/index.js.map  
npm notice 6.7kB  README.md          
npm notice 84B    .github/FUNDING.yml
npm notice === Tarball Details === 
npm notice name:          redux-vuex                              
npm notice version:       0.3.2                                   
npm notice filename:      redux-vuex-0.3.2.tgz                    
npm notice package size:  11.3 kB                                 
npm notice unpacked size: 31.1 kB                                 
npm notice shasum:        f5da59fcbd63383588022286bb573d60b48277d7
npm notice integrity:     sha512-8WR0jZ1ybLF+W[...]vxKBWxhH6WPng==
npm notice total files:   11                                      
npm notice 

tar -xvf redux-vuex-0.3.2.tgz -C .
tree package/

package/
โ”œโ”€โ”€ dist
โ”‚ย ย  โ”œโ”€โ”€ index.js
โ”‚ย ย  โ””โ”€โ”€ index.js.map
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ src
โ”‚ย ย  โ”œโ”€โ”€ index.js
โ”‚ย ย  โ”œโ”€โ”€ map-actions.js
โ”‚ย ย  โ”œโ”€โ”€ map-state.js
โ”‚ย ย  โ””โ”€โ”€ mixin.js
โ””โ”€โ”€ webpack.config.js

2 directories, 9 files

But I did notice there were declation files generated into the dist folder of your latest code base..

tree dist/

dist/
โ”œโ”€โ”€ helper.d.ts
โ”œโ”€โ”€ index.d.ts
โ”œโ”€โ”€ index.js
โ”œโ”€โ”€ index.js.map
โ”œโ”€โ”€ map-actions.d.ts
โ”œโ”€โ”€ map-state.d.ts
โ”œโ”€โ”€ provide-store.d.ts
โ”œโ”€โ”€ tokens.d.ts
โ””โ”€โ”€ types.d.ts

errr........did we accidently ignore too many while publishing?

Binding Store to the Vue Instance

With vuex, we create a store and export it. In the main.js file where we are mounting the application, we bind the store the main element like so.

new Vue({
    router,
    store,
    el: '#app',
    render: createElement => createElement(Main)
});

What is the equivalent of this in redux-vuex? How does the store bind to the main Vue instance?

I can see the use of the connect function.

connect({
  Vue,
  store,
  actions, // optional
  binding // optional: public store binding on vue instance (by default 'store')
});

I want to know how it maps this store to the main Vue instance. Does it require any extra configuration to be written or is the store variables available using import { mapState } from 'redux-vuex' in any component?

Vue3 Options API Support

We are upgrading our Project to Vue3, but we are continuing to use Options API. When trying to upgrade this library, we couldn't get it working as this seems to be have re-written exclusively for Composition API. Was this intentional? If so, are there any plans to provide support for Options API as well?

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.