javascript - 如何监听来自 vuex 的计算数组的变化
问题描述
我有一个计算数组,它是从商店的状态组装而成的:
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
我的问题:如果我更改了 input 的值,则不会触发计算的 setter。我会收到消息
“错误:[vuex] 不要在突变处理程序之外改变 vuex 存储状态。”
我知道我不能直接修改状态,但我不知道如何发送动作作为官网的例子。有人可以帮忙吗?非常感谢。
解决方案
v-model
仅当您映射tabList
到它时才有效(类似于v-model="tabList"
在组件中。
您必须使用value
and@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>
推荐阅读
- javascript - 如何验证 keyup 事件的数字间隔?
- excel - 为什么在用于导出到 pdf 的 VBA 代码上出现运行时错误“-2147417848 (80010108)”,在旧版 Excel 上运行良好?
- docker - 在 docker 容器中运行 systemd 会导致主机崩溃
- vba - 正确使用 IF-Else 语句
- python-3.x - 如何从列表中提取一些特定的字符串并将它们存储在beautifulsoup的变量中?
- vb.net - 在结构中使用字典
- django - 使用 Django 查询/显示多连接数据的最佳方法
- ios - 如何根据时间字段(自 1970 年午夜以来的秒数)获取日期?
- python-3.x - 使用 Twitter 提取地理位置的全名和国家代码
- sass - Gulp watch 只执行一次