0

I'm trying to use Vuex and I need to use methods inside a computed property as it is in my real project. I can't figure it out how to call the method and store the data in Vuex.

This is a simple example to show what I need to achieve:

my store:

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

Vue.use(Vuex);

export const store = new Vuex.Store({
    state: {
          calculations: {
              number: 1,
              letter: 'a',

              combinationA:'test',
          }
    },
    getters:{
    },
    mutations:{
        commit_number(state, val){state.calculations.number = val},
        commit_letter(state, val){state.calculations.letter = val},
        commit_combinationA(state, val){state.calculations.combinationA = val},
    },
    actions: {
    }
})

and this is my component

<template>
<div>
    <div>
        choose a number:
            <input v-model="number" type="number">
    </div>
<br>
<br>
    <select  v-model="letter" > 
        choose a letter
        <option value="a">a</option>
        <option value="b">b</option>
        <option value="c">c</option>
    </select>

<p>combination A: {{ combinationA }}</p>
<p>combination A without Vuex: {{ combination_no_vuex }}</p> 

</div>
</template>

<script>

export default {

    methods: {
        MethodCombinationA(letter, number){
            let result = String(letter).concat(number);
            return result;
        },
    },
    computed: {
        number: {
            get () { return this.$store.state.calculations.number;},
            set (value) { this.$store.commit('commit_number', value); }
        },
        letter: {
            get () { return this.$store.state.calculations.letter;},
            set (value) { this.$store.commit('commit_letter', value ); }
        },

        combinationA: {
           get () { return this.$store.state.calculations.combinationA;},
        // set (value) { this.$store.commit('commit_combinationA', this.MethodCombinationA(this.letter, this.number) ); }
        //
        // not working, this is the idea
        },

        combination_no_vuex() {
            return this.MethodCombinationA(this.letter, this.number);
        }
    }
}
</script>

Of course the computed property 'combination_no_vuex' is working as expected, and I would like to store/commit 'combinationA' as 'combination_no_vuex' and then using it in other components. I know Is pretty basic thing, but I'm stuck at the moment!

--edit-- I'm pretty sure this is not the best idea, but somehow it works:

I added an action:

    actions: {
        commit_combinationA(context, payload) {
            context.commit('commit_combinationA', payload);
          }
        }

then, when I get the computed property, it fires the method, then I dispatch it using a watch.

<template>
<div>
    <div>
        choose a number:
            <input v-model="number" type="number">
    </div>
<br>
<br>
    <select  v-model="letter" > 
        choose a letter
        <option value="a">a</option>
        <option value="b">b</option>
        <option value="c">c</option>
    </select>

<p>combination A: {{ combinationA }}</p>
<p>combination A alias: {{ combinationAalias }}</p>
<p>combination A without Vuex: {{ combination_no_vuex }}</p> 

</div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex';
export default {

    methods: {
        MethodCombinationA(letter, number){
            const result = String(letter).concat(number);
            return result;
        },
    },
    computed: {
        number: {
            get () { return this.$store.state.calculations.number;},
            set (value) { this.$store.commit('commit_number', value); }
        },
        letter: {
            get () { return this.$store.state.calculations.letter;},
            set (value) { this.$store.commit('commit_letter', value ); }
        },
        combinationA: {
            get () { return this.MethodCombinationA(this.letter, this.number)},
        },
        combinationAalias(){
            return this.$store.state.calculations.combinationA;
        },
        combination_no_vuex() {
            return this.MethodCombinationA(this.letter, this.number);
        }
    },
    watch: {
        combinationA(value){
            this.$store.dispatch('commit_combinationA', value );
        }
    },
}
</script>
2
  • You need to call an action from your component. Create actions that execute the commit, then run a this.$store.dispatch('action_name', props) from your component. Commented Sep 5, 2019 at 16:04
  • 1
    isn't necessary use actions for synchronous flow. Commented Sep 5, 2019 at 23:54

2 Answers 2

1
methods: {

  MethodCombinationA(letter, number){
    return String(letter).concat(number);
  },

},


computed: {

  number: {
    get() { return this.$store.state.calculations.number; },
    set(value) { this.$store.commit('commit_number', value); },
  },

  letter: {
    get() { return this.$store.state.calculations.letter; },
    set(value) { this.$store.commit('commit_letter', value); },
  },

  combinationA() {
    return this.$store.state.calculations.combinationA;
  },

},


watch: {

  number(value) {
    this.$store.commit('commit_combinationA', this.MethodCombinationA(this.letter, value));
  },

  letter(value) {
    this.$store.commit('commit_combinationA', this.MethodCombinationA(letter, this.value));
  },

},
Sign up to request clarification or add additional context in comments.

2 Comments

thanks, but I believe is not very dynamic as I wanted. I prefer the method returning a value. Anyway I can't understand why is nt working set(value) on computed 'combinationA()'. Any idea?
ok, I changed the code to make the method returning a value like your want. set(value) works only if you use combinationA in v-model, or when you try to change the combinationA value directly, e.g. this.combinationA = 'new value';
0

I answering to myself, I find out is better put the logic into the store.

Basically the computed property return a method value. Usign the parameters the method is, of course, riusable.

 <div id="app">
  <div>
    choose a number:
    <input v-model="number" type="number">
  </div>

  <br>

   <select v-model="letter" > 
     choose a letter
     <option value="a">a</option>
     <option value="b">b</option>
     <option value="c">c</option>
   </select>

  <p>combination A: {{ combinationA }}</p>

</div>

and js:

const store = new Vuex.Store({
  state: {
    number: 1,
    letter: "a"
  },
  mutations: {
    commit_number(state, val) {
      state.number = val;
    },
    commit_letter(state, val) {
      state.letter = val;
    }
  },
  getters: {
    combinationA(state) {
      return (obj1, obj2) => {
        return String(obj1).concat(obj2);
      }
    }
  }
});

new Vue({
  el: "#app",
  store,
  computed: {
    number: {
      get() { return this.$store.state.number; },
      set(value) { this.$store.commit("commit_number", value); }
    },
    letter: {
      get() { return this.$store.state.letter; },
      set(value) { this.$store.commit("commit_letter", value); }
    },
    combinationA(){ return this.$store.getters.combinationA(this.number, this.letter); }
  }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.