vue.js - 更改组件时更新 Vuex 存储中的数组中的项目
问题描述
在我的 Vuexstore
中有一组注释。每个音符都由一个 表示<textarea>
。我有一个显示每个注释的 NoteArray 组件:
// NoteArray.vue
export default {
name: "NoteArray",
components: { Note },
computed: {
...mapState({
notes: state => state.notes // get array of Notes from store
})
},
template: `
<div v-for="note in notes">
<!-- make one Note per note in array -->
<Note :contents.sync="note.contents"></Note>
</div>`
}
// Note.vue
export default {
name: "Note",
props: ["contents"], // recieve contents from NoteArray
template: `<textarea v-model="contents"></textarea>`
}
如果我不使用 Vuex,此设置可能会正常工作,但我希望每个 Note 的内容由我的商店中的单个数组表示:
// index.ts
let store = new Vuex.Store({
state: {
notes: [{contents: ""}] // will have a mutation to add/remove notes
}
}
现在,我正在使用v-model
将每个 Note 的内容附加到自身。这适用于单向绑定——Notes 的初始状态很好地向下传播。尝试更改注释时会出现问题。此处将使用sync
修饰符来建立双向绑定,而无需我定义任何输入事件。
Vuex 不是这样——我只能使用突变来修改状态。启用严格模式后,上面的示例会导致错误[vuex] do not mutate vuex store state outside mutation handlers
。
此处的解决方法是定义一个由给定 Note 调用的突变,该突变会@input
更改该 Note 的值contents
。我能想到的唯一方法是定义一个访问内容并更改它的突变(而不是v-model
and sync
):
// index.ts
...
mutations: {
update_note(state, payload) {
state.notes[payload.index] = payload.context
}
}
...
...但这要求每个 Note 知道并且能够将其在state.notes
数组中的索引传递给突变。但是,每个 Note 都完全不知道其上下文 - 他们没有此信息。
我不确定从这里去哪里 - 我怎样才能让每个 Note 的值在用户更改它们时contents
更新?store
我希望 NoteArray 和 Note 保持它们自己的组件。
解决方案
经过一番挖掘,事实证明,您所要做的就是放弃v-model
并$emit('update:contents', $event.target.value)
在. 实际上并不需要我最初的答案所包含的所有其他内容。@input
<textarea>
这是一个工作示例。
如您所见,注释已更新,没有任何内容commit
,并且App.vue
正确显示。我将测试放入App.vue
以确保它们在状态中更新,而不仅仅是vm
在NoteList.vue
.
我添加了唯一标识符,因为我发现,如果没有它们,删除 note 时<textarea>
会显示错误的内容(来自 notes 数组中的下一个注释)。
这正是要避免按索引键控的原因。(阅读本文档部分末尾的警告)。
现在,完全公平地说,我真的不明白为什么修改通过.sync
不会触发“不要在商店外变异”警告。要回答这个问题,必须深入研究究竟做了.sync
什么。或者它可能与不改变对象的结构有关。不太确定。
无论如何,这样做的正确方法是调度一个动作,update:contents
该动作将提交一个更新存储的突变:
示例:https ://codesandbox.io/s/frosty-feather-lhurk?file=/src/components/NoteList.vue 。
另一个注意事项:正如这个讨论所示,在状态属性之前prop.sync
没有使用“神奇地工作”开箱即用,所以它确实需要显然不再需要的dispatch
+ 。commit
推荐阅读
- jquery - Ajax JQuery - 将返回的变量 + 输入按钮和 Span 附加到 Div
- tensorflow - 目标检测模型卡在低 mAP
- vim - 为什么 Vim 会认为一个文件不是只读的?
- arrays - 为什么我不能使用字节或文件作为有效负载调用 sagemaker 端点
- node.js - SurveyMonkey API 使用 NodeJS 创建调查
- c# - 基于在 C# 中选中的单选按钮自动填充文本框?
- c++ - C++ 并发队列按引用或值推送
- php - 将数组转换为普通数组
- javascript - TypeScript 参数定义覆盖
- xml - 在 Android Studio 上将 apk 安装到虚拟设备时出错