Как прослушать изменения массива в computed, которое исходит от vuex - PullRequest
0 голосов
/ 03 октября 2019

У меня есть массив computed, который собран из состояния магазина:

computed: {
  ...mapGetters([
    '$tg',
  ]),
  ...mapState({
    podcastList: state => state.listening.podcastList,
  }),
  tabList: {
    get() {
      const questionTitle = this.$tg('questions');
      const list = this.podcastList.map((poadcast, index) => ({
        ...poadcast,
        title: `${questionTitle}${index + 1}`,
        answers: [...poadcast.answers],
      }));
      return list;
    },
    set(value) {
      // I want dispatch action here..
      console.log('set', value);
    },
  },
}

конструкция podcastList является массивом объектов:

[ 
  { 
    id: 1,  
    answers: [ 
      { id: 1, content:'foo'}, { id: 2, content: 'bar'}
    ]
  }, //.....
]

Я использую v-for, чтобы сделать группу из input, которая связана с answers. Это выглядит так:

<div class="columns is-vcentered" v-for="(answer, index) in tab.answers" :key="index">
 <input type="text" v-model="answer.content"/>
</div>
// tab is an element of my tabList

Мой вопрос: если я изменил значение ввода, вычисляемый установщик не сработает. Я получу сообщение

«Ошибка: [vuex] не изменяет состояние хранилища vuex вне обработчиков мутаций.»

Я знаю, что не могу изменить состояние напрямую,но я не знаю, как отправить действие на примере официального сайта . Кто-нибудь может помочь? Большое спасибо.

1 Ответ

1 голос
/ 03 октября 2019

v-model будет работать только в том случае, если вы отобразите tabList в нем (что-то вроде v-model="tabList" в компоненте.

Вам придется изменить каждый ответ напрямую, используя value и @input вместо v-model:

<div class="columns is-vcentered" v-for="(answer, index) in tab.answers" :key="index">
 <input type="text" :value="answer.content"
       @input="$store.commit('updateAnswer', { podcastId: tab.id, answerId: answer.id, newContent: $event.target.value })" />
</div>
// tab is an element of my tabList

И мутация updateAnswer, например:

mutations: {
  updateAnswer (state, { podcastId, answerId, newContent }) {
    state.listening.podcastList
        .find(podcast => podcast.id === podcastId)
        .map(podcast => podcast.answers)
        .find(answer => answer.id === answerId).content = newContent;
  }
}

-

Возможно, вы уменьшите шаблон, создавметод:

methods: {
  updateAnswer(tab, answer, event) {
    this.$store.commit('updateAnswer', { podcastId: tab.id, answerId: answer.id, newContent: event.target.value });
  }
}

И использовать его следующим образом:

<input type="text" :value="answer.content" @input="updateAnswer(tab, answer, $event)" />


Или путем создания компонента (который может быть функциональным):

Vue.component('answer', {
  template: `
    <input type="text" :value="answer.content"
           @input="$store.commit('updateAnswer', { podcastId: tab.id, answerId: answer.id, newContent: $event.target.value })" />
  `
  props: ['tab', 'answer']
})

И используйте это как:

<div class="columns is-vcentered" v-for="(answer, index) in tab.answers" :key="index">
 <answer :tab="tab" :answer="answer"/>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...