我正在尝试将用户输入从一个表单绑定到我的vuex存储中的一个状态。
状态如下所示:
customers: [
  {firstName: "", lastName: "", age: ""},
  {firstName: "", lastName: "", age: ""},
  {firstName: "", lastName: "", age: ""}
]我尝试在调用get和set方法的计算属性上使用v-model。我找到了一个解释here。
这对于对象非常有效,但不幸的是,没有解释如何在对象数组上使用它。
我在找这样的东西:
computed: {
  firstName: {
    get () {
      return this.$store.state.customers[i].firstName
    },
    set (value) {
      this.$store.commit('changeFirstname', {value, index})
    }
  }
}但显然这不起作用,因为我不能将索引传递给computed属性。有人有解决这个问题的办法吗?这是深度观察者的一个很好的用例吗?
这是我的第一个问题,如果我忘记了什么或者做错了什么,请告诉我,这样我就可以提高我的提问能力。谢谢!
发布于 2019-07-02 13:10:49
当您的数据不是平面数据时,Vuex可能有点麻烦。有关这方面的更多信息,请参阅https://forum.vuejs.org/t/vuex-best-practices-for-complex-objects/10143。
解决这个问题的一种方法是抛弃v-model,直接使用:value和@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)
    }
  }
})<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>
保留v-model的另一种方法是引入单独的组件来容纳每个客户。通常,当使用v-for进行任何涉及编辑的操作时,值得考虑引入一个新组件。
在这个例子中,有一种不对称性,即从父节点中的商店读取客户,并将其写入子节点中的商店。我觉得这有点不舒服。也许如果每个客户都有一个id,那么这个id就可以作为一个道具而不是customer对象传递给孩子,让孩子去获取和设置它感兴趣的单个客户。
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()
    }
  }
})<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>
关于你关于深度观察者的问题,我相信你所描述的会涉及到改变商店外的状态,然后让一个观察者让商店知道这一点。商店实际上没有什么可做的,因为状态已经改变了。显然,这违反了仅在商店的mutations中改变商店状态的“规则”。
https://stackoverflow.com/questions/56841694
复制相似问题