Используйте v-bind для массива объектов в Vuex - PullRequest
2 голосов
/ 01 июля 2019

Я пытаюсь привязать пользовательский ввод из формы к состоянию в моем магазине vuex.

Состояние выглядит следующим образом:

customers: [
  {firstName: "", lastName: "", age: ""},
  {firstName: "", lastName: "", age: ""},
  {firstName: "", lastName: "", age: ""}
]

Я пытался использовать v-модель для вычисляемого свойства, которое вызывает метод get и set.Я нашел объяснение здесь .

Это прекрасно работает для объекта, но, к сожалению, нет объяснения, как использовать это для массива объектов.

Я ищу что-то вроде этого:

computed: {
  firstName: {
    get () {
      return this.$store.state.customers[i].firstName
    },
    set (value) {
      this.$store.commit('changeFirstname', {value, index})
    }
  }
}

Но, очевидно, это не сработало, потому что я не могу передать индекс вычисляемому свойству.У кого-нибудь есть решение для этого?Это хороший пример использования для глубокого наблюдателя?

Это мой первый вопрос, пожалуйста, дайте мне знать, если я что-то забыл или сделал что-то не так, чтобы я мог улучшить свои вопросы.Спасибо!

1 Ответ

0 голосов
/ 02 июля 2019

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 для всего, что связано с редактированием, стоит подумать о введении нового компонента.

В этом примере существует асимметрия, заключающаяся в том, что клиенты читаются из магазина в родительском и записываются в магазин в дочернем. Я нахожу это немного неудобным. Возможно, если бы у каждого клиента был свой идентификатор, тогда этот идентификатор мог бы быть передан ребенку в качестве реквизита вместо объекта клиента, оставив ребенку возможность получить и установить отдельного клиента, которого он интересует.

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.

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...