Home » vue » Helper method to define Vue.js computed properties

Helper method to define Vue.js computed properties

Posted by: admin November 26, 2021 Leave a comment

Questions:

I’m using Vue.js with Vuex modules. In almost every module I have an action & mutation called updateProp which looks like this:

updateProp ({commit}, payload) {
  commit('updateProp', payload)
}
updateProp (state, payload) {
  state[payload.propName] = payload.newVal
}

So then when I define some computed property that has a source in the Vuex I write:

myComputedValue: {
  get () {
    return this.$store.state.vuexModuleName.propertyName
  },
  set (newValue) {
    this.$store.dispatch('vuexModuleName/updateProp', {propName: 'propertyName', newVal: newValue})
  }
}

Very often I have to define multiple computed values like this, so I thought I’ll create a global helper method instead:

Vue.prototype.$computedDefHelper = (computedPropModel, computedPropName) => {
  return {
    get () {
      return this.$store.state[computedPropModel][computedPropName]
    },
    set (newVal) {
      this.$store.dispatch(`${computedPropModel}/updateProp`, {propName: computedPropName, newVal: newVal})
    }
  }
}

So I’ll be able to define these computed values in shorter way:

myComputedValue: this.$computedDefHelper('vuexModuleName', 'propertyName')

But this doesn’t work – I get an error that $computedDefHelper is not a function – tried various things like using it like a mixing/plugin/non-arrow function etc. but nothing seem to work – is it even possible?

Any tips will be highly appreciated.

EDIT:

Only way I’ve managed it to work at the moment is to define it as a helper and import it in every module I want to use it so:

import { computedDefHelper } from '@/helpers/globalHelpers'

so then I can use it to define computed value:

myComputedValue: computedDefHelper('vuexModuleName', 'propertyName')

But I would like to avoid importing this and have it already built-in (globally) in every component.

EDIT 2:

I think this might be related with order of triggering / lifecycle Vue.js stuff, since if I console log this method in created hook, it looks fine, so probably it’s something related that these computed methods object definitions are somehow parsed earlier than this global method is registered ?

EDIT 3:

I’ve created quickly a simpler version what I want to achieve (not working) at code sandbox to play around with: https://codesandbox.io/s/x3661n317o

Answers:

You can define a mixin method in your globalHelpers.js, for example updater:

const computedDefHelper = {
  install(Vue, options) {
    Vue.mixin({
      methods: {
        updater: function(name, payload) {
          return this.$store.dispatch(`${name}/updateProp`, payload);
        }
      }
    });
  }
};
export default computedDefHelper;

Then import it in your main.js:

import computedDefHelper from '@/helpers/globalHelpers';
Vue.use(computedDefHelper);

You can now use it in every components like this:

this.updater('vuexModuleName', payload)

where payload can be reworked according to what you want as parameter.

###

I think you need to create a plugin for this and install this helper property with the Vue instance like this:

  import computedDefHelper from '@/helpers/globalHelpers'

  const Plugin = {

    install: (myVue, options) => {
      const aVue = myVue;
      aVue.prototype.$computedDefHelper = computedDefHelper;
    },
  };

  export default Plugin;

and in your main.js file like this:

Vue.use(Plugin);