Как элегантно использовать v-model и Vuex store? - PullRequest
0 голосов
/ 30 января 2019

Я ищу чистый способ использования v-model и vuex store.

Vuex предоставляет несколько вспомогательных методов, которые довольно полезны, но немного раздражают при использовании с v-model.

Сегодня я использую v-модель и мое модульное хранилище как

computed: {
  type: {
    get() {
      return this.$store.state.mymodule.type;
    },
    set(newValue) {
      this.$store.dispatch('mymodule/setType', newValue)
    }
}

. Это работает, НО мне показалось, что лучше использовать выгоду от помощников vuex, чтобы избежать стандартного кода (это. $ Store, имя модуля,...)

Хорошо, поэтому я сначала хочу избавиться от имени модуля.Vuex предоставляет замечательные createNamespacedHelpers , которые возвращают модульные помощники.

Давайте использовать его:

import { createNamespacedHelpers } from 'vuex'

const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')

Итак, теперь у нас есть чистые функции mapState и mapActions, которыевыделенный модуль.

computed: {
  ...mapState(['type']) // No need here to specify module name :)
}

Довольно круто, но поскольку у mapState есть только функция get, я не могу установить функцию отправки для обновления данных ...

В случае использования v-модели,Я нахожу помощников непригодными.Я не могу использовать mapState, поэтому я не могу использовать createNamespacedHelpers.

Итак: Как я могу использовать преимущества вспомогательных функций Vuex и v-модели для совместной работы?

Ответы [ 3 ]

0 голосов
/ 31 января 2019

Способ, который я наконец нашел наиболее читаемым, следующий:

import { createNamespacedHelpers } from 'vuex'

const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')

Используется так:

computed: {
  ...mapGetters(['type'])
},
methods: {
  ...mapActions(['setType'])
}

И без v-модели

<input :value="type" @input="setType($event.target.value)">
0 голосов
/ 14 февраля 2019

Попробуйте это.

// in some utils/vuex.js file 
export const mapSetter = (state, setters = {}) => (
  Object.keys(state).reduce((acc, stateName) => {
    acc[stateName] = {
      get: state[stateName],
   };
   // check if setter exists
   if (setters[stateName]) {
      acc[stateName].set = setters[stateName];
   }

   return acc;
 }, {})
);

В вашем файле component.vue

  import { mapSetter  } from 'path/to/utils/vuex.js';
  ...

  export default {
    name: 'ComponentName',
    computed: {
      ...mapSetter(
        mapState({
          result: ({ ITEMS }) => ITEMS.result,
          total: ({ ITEMS }) => ITEMS.total,
          current: ({ ITEMS }) => ITEMS.page,
          limit: ({ ITEMS }) => ITEMS.limit,
        }),
        {
          limit(payload) {
            this.$store.dispatch({ type: TYPES.SET_LIMIT, payload });
          },
        },
      )
    },
  }

теперь привязка v-модели должна работать.

0 голосов
/ 30 января 2019

Вы не можете.Не существует элегантного способа объединить помощников с v-моделью.Но v-модель - это просто синтаксический сахар, поэтому, возможно, самый читаемый способ - использовать помощников

computed: {
  ...mapGetters('path/to/module', ['type'])
},
methods: {
  ...mapActions('path/to/module', ['setType'])
}

без v-модели

<input :value="type" @input="setType">
...