web-dev-qa-db-fra.com

Vue 2 - vuex mapGetters and pass params

Est-il possible de passer des paramètres avec mapGetters ?

J'ai ceci dans l'instance principale de Vue:

computed: {
    filterAuthors() {
        return this.$store.getters.filterAuthors(this.search.toLowerCase());
    }
}

this.search est lié au champ de saisie via v-model = "search = , et dans mon exemple Vuex, j'ai ce getters:

getters: {
    filterAuthors: (state) => (search) => {
        return state.authors.filter((author) => {
            return author.name.toLowerCase().indexOf(search) >= 0;
        })
    }
},

Celui-ci fonctionne bien, mais j'essaie de trouver un moyen (s'il est possible) d'utiliser mapGetters et de passer l'argument. Cela peut-il être fait?

6
Sasha

Cela peut en effet être fait! mapGetters mappe simplement this.yourGetterName à ceci. $ store.getters.yourGetterName (voir docs )

Donc pour accomplir ce que vous voulez:

import { mapGetters } from 'vuex'

export default {
  // ... the rest of your Vue instance/component
  computed: {
    // Mix your getter(s) into computed with the object spread operator
    ...mapGetters([
      'filteredAuthors'
      // ...
    ]),
    // Create another computed property to call your mapped getter while passing the argument
    filteredAuthorsBySearch () {
      return this.filteredAuthors(this.search.toLowerCase())
    }
  }
}
4
David Roberts

C'est ce que vous pouvez faire de plus près si vous voulez passer le paramètre dans le magasin. Cependant, il serait préférable de le paramétrer en tant que partie intégrante du magasin et de définir le champ input en tant que propriété calculée avec le getter et le setter correspondants pour mettre à jour l'état. Et vous pouvez ensuite utiliser mapGetter pour obtenir les résultats.

const { mapGetters } = Vuex

const authorsInput = [{ name: 'Stephen King'}, { name: 'Neal Stephenson'}, { name: 'Tina Fey'}, { name: 'Amy Poehler'}, { name: 'David Foster Wallace'}, { name: 'Dan Brown'}, { name: 'Mark Twain'}]

const store = new Vuex.Store({
  state: {
    srchInput: '',
    authors: authorsInput
  },
  getters: {
    filteredAuthors: (state) => state.authors
      .filter((author) => author
        .name
        .toLowerCase()
        .indexOf(state.srchInput.toLowerCase()) >= 0)
      .map((author) => author.name)
  },
  mutations: {
    UPDATE_SRCH_INPUT: (state, input) => state.srchInput = input
  },
})

new Vue({
  el: '#app',
  store,
   computed: Object.assign({
    srchInput: {
      get () { return store.state.srchInput},
      set (val) { store.commit('UPDATE_SRCH_INPUT', val) } 
    }
  }, mapGetters([
    'filteredAuthors'
  ]))
})
filterAuthors: (state) => (search) => {
        return state.authors.filter((author) => {
            return author.name.toLowerCase().indexOf(search) >= 0;
        })
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.js"></script>
<div id="app">
 <div>
    <input type="text" v-model="srchInput"/>
    <ul>
      <li v-for="author in filteredAuthors">{{author}}</li>
    </ul>
  </div>
</div>

1
kevguy