首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何侦听由vuex产生的计算数组的变化

如何侦听由vuex产生的计算数组的变化
EN

Stack Overflow用户
提问于 2019-10-03 03:20:10
回答 1查看 761关注 0票数 0

我有一个由存储状态组装的计算数组:

代码语言:javascript
代码运行次数:0
运行
复制
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的构造是一个对象数组:

代码语言:javascript
代码运行次数:0
运行
复制
[ 
  { 
    id: 1,  
    answers: [ 
      { id: 1, content:'foo'}, { id: 2, content: 'bar'}
    ]
  }, //.....
]

我使用v-for来创建一个由input组成的组,它是answers的绑定。看上去:

代码语言:javascript
代码运行次数:0
运行
复制
<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存储状态之外的变异处理程序。

我知道我不能直接修改状态,但我不知道如何将该操作作为官方网站的示例进行调度。有人能帮忙吗?非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-03 03:55:04

v-model只有在将tabList映射到它(类似于组件中的v-model="tabList" )时才能工作。

您必须直接更改每个答案,方法是使用value@input代替v-model

代码语言:javascript
代码运行次数:0
运行
复制
<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突变就像:

代码语言:javascript
代码运行次数:0
运行
复制
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;
  }
}

--

您也许可以通过创建一个方法来减少样板:

代码语言:javascript
代码运行次数:0
运行
复制
methods: {
  updateAnswer(tab, answer, event) {
    this.$store.commit('updateAnswer', { podcastId: tab.id, answerId: answer.id, newContent: event.target.value });
  }
}

并把它当作:

代码语言:javascript
代码运行次数:0
运行
复制
<input type="text" :value="answer.content" @input="updateAnswer(tab, answer, $event)" />

或者通过创建一个组件(可以是功能性的):

代码语言:javascript
代码运行次数:0
运行
复制
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']
})

并把它当作:

代码语言:javascript
代码运行次数:0
运行
复制
<div class="columns is-vcentered" v-for="(answer, index) in tab.answers" :key="index">
 <answer :tab="tab" :answer="answer"/>
</div>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58211882

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档