Search code examples
typescriptvue.jsvuex

How to create a Utils class for Vue.js that has access to Vuex this.$store


I have a case where I want to fetch state from the Vuex this.$store. I researched and found out having a custom plugin installing an instance method might do the trick.

This is my plugin logic:

index.ts

import _ from 'lodash'

export default {
  install: function (Vue) {
    Vue.prototype.$fetchVillager = function () {
      const players = this.$store.state.players
      const village = this.$store.state.villages.find(value => value.id === 0)
      const villagerIds = village.villagers

      const villagers = _.filter(players, function (player) {
        return villagerIds.includes(player.id)
      })
      if (!_.isNil(villagers)) {
        return villagers
      }
      return []
    }
  }
}

As you can see I am using this.$store.state.players and therefore am accessing Vuex state. Using all this is pretty straightforward and does work as you can see here:

computed: {
    villagers: function () {
      return this.$fetchVillager()
    }
  }

However since I used Vue.use(MyPlugin) this function now is available everywhere. I kinda would like to restrict it to only those components I wanna use it in (there are three atm.).

So basically I'd love to have a simple import VillageServices from '@/services/villageServices.ts and just use the exposed functions from there. That surely does not work since with this approach there is no way to access Vuex this.$store since I am not bound to a Vue instance with that imported class.

Is there a way to achieve what I'd like to do?


Solution

  • I think you could simply use a mixin.

    const villagers = {
        methods: {
            $fetchVillagers() {
                // use this.$store
            }
        }
    };
    
    const myComponent = new Vue({
        mixins: [villagers],
        computed: {
            villagers() {
                return this.$fetchVillagers();
            }
        }
    });