我正在尝试将用户输入从表单绑定到我的 vuex 商店中的状态。
状态看起来像这样:
customers: [
{firstName: "", lastName: "", age: ""},
{firstName: "", lastName: "", age: ""},
{firstName: "", lastName: "", age: ""}
]
Run Code Online (Sandbox Code Playgroud)
我尝试在调用 get 和 set 方法的计算属性上使用 v-model 。我在这里找到了解释。
这对于对象来说非常有效,但不幸的是没有解释如何在对象数组上使用它。
我正在寻找这样的东西:
computed: {
firstName: {
get () {
return this.$store.state.customers[i].firstName
},
set (value) {
this.$store.commit('changeFirstname', {value, index})
}
}
}
Run Code Online (Sandbox Code Playgroud)
但显然这不起作用,因为我无法将索引传递给计算属性。有人对此有解决方案吗?对于深度观察者来说,这是一个很好的用例吗?
这是我的第一个问题,如果我忘记了什么或者做错了什么,请告诉我,以便我改进我的提问。谢谢!
当你的数据不平坦时,Vuex 可能会有点麻烦。有关更多信息,请参阅https://forum.vuejs.org/t/vuex-best-practices-for-complex-objects/10143 。
解决这个问题的一种方法是放弃v-model并直接使用:valueand @input。我在示例中模拟了一家商店,但希望大家清楚发生了什么。如果您发现比传递对象本身更容易,则可以轻松获取客户的索引。
const storeCustomers = Vue.observable([
{firstName: "A", lastName: "", age: ""},
{firstName: "B", lastName: "", age: ""},
{firstName: "C", lastName: "", age: ""}
])
function storeGetCustomers () {
return storeCustomers
}
function storeUpdateCustomerFirstName (customer, value) {
customer.firstName = value
}
new Vue({
el: '#app',
computed: {
customers () {
return storeGetCustomers()
}
},
methods: {
onFirstNameInput (customer, value) {
storeUpdateCustomerFirstName(customer, value)
}
}
})Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
<div v-for="customer in customers">
<input :value="customer.firstName" @input="onFirstNameInput(customer, $event.target.value)">
</div>
<p>
{{ customers }}
</p>
</div>Run Code Online (Sandbox Code Playgroud)
保留的另一种选择v-model是引入一个单独的组件来保留每个客户。一般来说,当用于涉及v-for编辑的任何内容时,值得考虑引入新组件。
在此示例中存在不对称性,因为从父级中的商店读取客户并将其写入子级中的商店。我觉得有点不舒服。也许如果每个客户都有一个 id,那么该 id 可以作为 prop 而不是客户对象传递给子级,让子级获取和设置它感兴趣的单个客户。
const storeCustomers = Vue.observable([
{firstName: "A", lastName: "", age: ""},
{firstName: "B", lastName: "", age: ""},
{firstName: "C", lastName: "", age: ""}
])
function storeGetCustomers () {
return storeCustomers
}
function storeUpdateCustomerFirstName (customer, value) {
customer.firstName = value
}
const child = {
props: ['customer'],
template: `
<div>
<input v-model="firstName">
</div>
`,
computed: {
firstName: {
get () {
return this.customer.firstName
},
set (value) {
storeUpdateCustomerFirstName(this.customer, value)
}
}
}
}
new Vue({
el: '#app',
components: {
child
},
computed: {
customers () {
return storeGetCustomers()
}
}
})Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
<child v-for="customer in customers" :customer="customer"></child>
<p>
{{ customers }}
</p>
</div>Run Code Online (Sandbox Code Playgroud)
对于您关于深度观察者的问题,我相信您所描述的内容将涉及改变商店外的状态,然后让观察者让商店知道这一点。实际上商店不需要做任何事情,因为状态已经改变了。显然,这会违反关于仅改变 store 内部的 store 状态的“规则” mutations。
| 归档时间: |
|
| 查看次数: |
1756 次 |
| 最近记录: |