Search code examples
javascriptvue.jsvuex

VueJS: Best practice for working with global object between components?


there is User.js class and user object(user = new User();).

The user object is being used in all nested components. in User class there are so many important methods.

How can I simply use/access this.user or this.$user and its methods in any component?

1-solution (temporary working solution): Setting user in vuex's store and define in all components' data:

data(){
  return {
    user:this.$store.state.user
  }
}

Cons: in every component, this should be added. Note: there are so many components.

2-solution: adding user to Vue's prototype like plugin:

Vue.prototype.$user = user

Cons: when user's data changes, it doesn't effect in DOM element (UI).

3-solution: putting to components's props.

Cons: in every component, this should be added. Note: Again there are so many components.

All of the solutions I found have issues, especially as the project gets larger and larger.

Any suggestion and solution will be appreciated!


Solution

  • Note: Applies for Vue 2x

    Proposal 1: Using getters from vuex

    • You could use getters along with mapGetters from Vuex to include users within computed properties for each component.

    Vuex

    getters: {
      // ...
      getUser: (state, getters) => {
        return getters.user
      }
    }
    

    component

    import { mapGetters } from 'vuex'
    computed: {
      ...mapGetters([getUser])
    }
    

    Proposal 2: add a watcher via plugin

    Vue

    // When using CommonJS via Browserify or Webpack
    const Vue = require('vue')
    const UserPlug = require('./user-watcher-plugin')
    
    // Don't forget to call this
    Vue.use(UserPlug)
    

    user-watcher-plugin.js

    const UserPlug = {
      install(Vue, options) {
        // We call Vue.mixin() here to inject functionality into all components.
    
        Vue.watch: 'user'
      }
    };
    
    export default UserPlug;
    

    Proposal 3: add a computed property user as plugin via mixin

    Vue

    // When using CommonJS via Browserify or Webpack
    const Vue = require('vue')
    const UserPlug = require('./user-watcher-plugin')
    
    // Don't forget to call this
    Vue.use(UserPlug)
    

    user-watcher-plugin.js

    const UserPlug = {
      install(Vue, options) {
        // We call Vue.mixin() here to inject functionality into all components.
    
        Vue.mixin({
          computed: {
            user: function() {
              return this.$store.state.user
            }
          }
        })
      }
    };
    
    export default UserPlug;