IT이야기

Vue.js - v-model에서 매개 변수를 전달하여 중첩된 속성 변경

cyworld 2022. 5. 15. 23:44
반응형

Vue.js - v-model에서 매개 변수를 전달하여 중첩된 속성 변경

v-for와 함께 어레이 '제품'을 표시했다.각 제품에는 '주문' 객체에 제품을 추가하는 버튼이 있다.개체 '순서'가

order: {
  products: [{
    quantity: 0,
    otherProperties
  }]
}

그 버튼을 두 번째로 클릭했을 때 1로 수량을 늘리고 싶다.

클릭한 개체를 전달하는 Vuex에서는

increaseQuantity(state, product){
  state.order.products.find((orderProduct)=>{
    return product.id === orderProduct.id
  }).quantity++;

지금까지는 좋다.크롬 개발 도구에서 수량 증가를 볼 수 있다.

까다로운 건, 어떻게 해야 할지 전혀 모르겠네, 쉽긴 하지만.버튼 옆에 있는 입력란에 각 제품의 수량을 보여주고 싶다.문제는 다음과 같은 v-model에서 선택한 제품이 필요하다는 것이다.

<div v-for="product in products" :key="product.id">
  <input v-model="order.products.find((orderProduct)=>{
    return product.id === orderProduct.id
  }).quantity" />
</div>

제품을 '주문' 객체에 추가하는 순간 0의 수량 값이 입력 필드에 표시되므로 DOM이 업데이트된다.그러나 수량이 바뀌어도 DOM에서는 아무것도 변하지 않는다.하지만 vuex 매장에서 수량이 바뀌었다.

이걸 해결할 방법이 있을까?v-model이 아닌 :value로 시도해봤지만 같은 문제였습니다.

이러한 변화를 사후 대응적으로 만드는 데 사용해야 한다.

increaseQuantity(state, product){
  let index= state.order.products.findIndex((orderProduct)=>{
    return product.id === orderProduct.id
  })
state.order.products.quantity++;
this.$set(state.order.products,index,state.order.products[index])

}

당신은 가게를 비반복적으로 변이시킨 것 같다. 즉, Vue가 당신의 변경 사항을 추적하지 않기 때문에 DOM은 업데이트되지 않는다.

나는 다음 조각으로 너의 코드를 조금 다시 작성했다.

const store = new Vuex.Store({
  state: {
    products: [
      {
        id: 1,
        quantity: 0
      },
      {
        id: 2,
        quantity: 0
      }
    ]
  },
  mutations: {
    ADD_PRODUCT(state, { id: productId, amount }) {
      const product = state.products.find(({ id }) => id === productId)
      if (product) {
        if (!product.hasOwnProperty('order')) {
          // this is the way to set data in a reactive-way
          Vue.set(product, 'order', true)
        } else {
          product.quantity = Number(amount)
        }
      }
    }
  },
  actions: {
    addProduct({ commit }, data) {
      commit('ADD_PRODUCT', data)
    }
  },
  getters: {
    getProducts: ({ products }) => products,
    getOrdered: ({ products }) => {
      return products.filter(product => {
        return product.hasOwnProperty('order') ? product : false
      })
    }
  }
})

Vue.component('Product', {
  props: ['product'],
  computed: {
    buttonText() {
      if (!this.product.order) {
        return 'ADD TO ORDER'
      } else {
        return 'SET ORDERED QUANTITY'
      }
    }
  },
  data() {
    return {
      amount: 0
    }
  },
  template: `
    <div>Product: {{ product.id }}, {{ product.quantity }}
      <button @click="addToOrder(product.id, amount)">{{ buttonText }}</button>
      <input
        v-if="product.order"
        type="number"
        v-model="amount"
        min="0"
        @input="addToOrder(product.id, amount)"
      >
    </div>`,
  methods: {
    addToOrder(id, amount) {
      this.$store.dispatch('addProduct', { id, amount })
    }
  }
})

Vue.component('Ordered', {
  props: ['product'],
  template: `
    <div>
      Product {{ product.id }} quantity: {{ product.quantity }}
    </div>
  `
})

new Vue({
  el: '#app',
  store,
  computed: {
    products() {
      return this.$store.getters.getProducts
    },
    ordered() {
      return this.$store.getters.getOrdered
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuex@3.5.1/dist/vuex.js"></script>
<div id="app">
  <div>
    <h3>PRODUCT LIST</h3>
    <product
      v-for="product in products"
      :key="product.id"
      :product="product"
    />
  </div>
  <hr />
  <h3>ORDERED LIST</h3>
  <ordered
    v-for="product in ordered"
    :key="`ordered-${ product.id }`"
    :product="product"
  />
</div>

제품만 바꿔준다는 생각이다.order전체 순서가 무엇인지 추적하기 위한 속성나는 또한 a를 만들었다.getter주문된 제품을 걸러내는 것(그래서 어느 시점에 필요한 제품만 있다면, 나는 그것을 그냥 그렇게 부른다.getter).

이것은 간단한 방법이다.

  • 입력 필드만으로 주문 금액을 설정할 수 있다.
  • 모든 제품에 대한 배열이 하나뿐입니다.
  • 제품이 자신의 상태를 추적한다(속성 및 금액).

에 반응성에 대한 자세한 내용은 https://vuejs.org/v2/guide/reactivity.html를 참조하십시오.

참조URL: https://stackoverflow.com/questions/63360149/vue-js-change-nested-property-by-passing-a-parameter-in-v-model

반응형