admin管理员组

文章数量:1431918

I'm cloning an array and using map to add a property to each object in the array. For some reason when I do this the added property is not being updated when used in v-model. Any ideas why this is happening?

In the below code typing in the text field does not update the item quantity. How can the code be altered so that it does?

<template>
  <v-data-table
    :headers="headers"
    :items="items"
  >
    <template v-slot:item.quantity="props">
      <v-text-field v-model="props.item.quantity"></v-text-field>
    </template>
  </v-data-table>
</template>

<script>
export default {
  props: {
    customer: {
      type: Object,
      required: true
    }
  },
  data: () => ({
    headers: [
      { text: 'ID', value: 'id' },
      { text: 'Description', value: 'description' },
      { text: 'Quantity', value: 'quantity' },
    ],
    items: []
  }),
  created() {
    this.initialize()
  },
  methods: {
    initialize() {
      const items = [...this.customer.items]
      items.map(item => {
        item.quantity = ''
      })
      this.items = items
    }
}
</script>

Customer is a JSON response from API

{
  "id": 1,
  "name": "Customer",
  "items": [
    {
      "id": 1,
      "product": 1707,
      "contract": null,
      "plu": "709000",
      "description": "ABC",
      "unit": 1,
      "price": "5.20"
    }
  ],
}

Update

Link to codepen - typing in the qty2 field does not update the data because it was added to the object with map.

I'm cloning an array and using map to add a property to each object in the array. For some reason when I do this the added property is not being updated when used in v-model. Any ideas why this is happening?

In the below code typing in the text field does not update the item quantity. How can the code be altered so that it does?

<template>
  <v-data-table
    :headers="headers"
    :items="items"
  >
    <template v-slot:item.quantity="props">
      <v-text-field v-model="props.item.quantity"></v-text-field>
    </template>
  </v-data-table>
</template>

<script>
export default {
  props: {
    customer: {
      type: Object,
      required: true
    }
  },
  data: () => ({
    headers: [
      { text: 'ID', value: 'id' },
      { text: 'Description', value: 'description' },
      { text: 'Quantity', value: 'quantity' },
    ],
    items: []
  }),
  created() {
    this.initialize()
  },
  methods: {
    initialize() {
      const items = [...this.customer.items]
      items.map(item => {
        item.quantity = ''
      })
      this.items = items
    }
}
</script>

Customer is a JSON response from API

{
  "id": 1,
  "name": "Customer",
  "items": [
    {
      "id": 1,
      "product": 1707,
      "contract": null,
      "plu": "709000",
      "description": "ABC",
      "unit": 1,
      "price": "5.20"
    }
  ],
}

Update

Link to codepen - typing in the qty2 field does not update the data because it was added to the object with map.

Share Improve this question edited Oct 25, 2019 at 14:48 bdoubleu asked Oct 25, 2019 at 12:44 bdoubleubdoubleu 6,1273 gold badges27 silver badges56 bronze badges 5
  • Try with v-slot:item.quantity="{ item }" v-model="item.quantity". – azeós Commented Oct 25, 2019 at 14:17
  • Can you please share the sample object of this.customer.items, in question, that would really help to solve your issue – chans Commented Oct 25, 2019 at 14:24
  • @azeós that doesn't work either – bdoubleu Commented Oct 25, 2019 at 14:34
  • @chans question updated – bdoubleu Commented Oct 25, 2019 at 14:34
  • The above approach will update the object , when you change the value in text box – chans Commented Oct 25, 2019 at 14:35
Add a ment  | 

2 Answers 2

Reset to default 1

The above code is working as expected, I've reproduced the same scenario in codepen

find the working code here: https://codepen.io/chansv/pen/gOOWJGJ?editors=1010

Try make changes to the first text box in the data-table for testing purpose and check the console it updates the items object on typing

<div id="app">
  <v-app id="inspire">
    <v-data-table
      :headers="headers"
      :items="desserts"
      :items-per-page="5"
      class="elevation-1"
    >
      <template v-slot:item.protein="props">
        <v-text-field
          v-model="props.item.protein"
          name="quantity"
          outlined
          @input="getdata"
          type="number"
        ></v-text-field>
      </template>
    </v-data-table>
  </v-app>
</div>


new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'left',
          sortable: false,
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
      ],
      desserts: [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0,
          iron: '1%',
        },
        {
          name: 'Ice cream sandwich',
          calories: 237,
          fat: 9.0,
          carbs: 37,
          protein: 4.3,
          iron: '1%',
        },
        {
          name: 'Eclair',
          calories: 262,
          fat: 16.0,
          carbs: 23,
          protein: 6.0,
          iron: '7%',
        },
        {
          name: 'Cupcake',
          calories: 305,
          fat: 3.7,
          carbs: 67,
          protein: 4.3,
          iron: '8%',
        },
        {
          name: 'Gingerbread',
          calories: 356,
          fat: 16.0,
          carbs: 49,
          protein: 3.9,
          iron: '16%',
        },
        {
          name: 'Jelly bean',
          calories: 375,
          fat: 0.0,
          carbs: 94,
          protein: 0.0,
          iron: '0%',
        },
        {
          name: 'Lollipop',
          calories: 392,
          fat: 0.2,
          carbs: 98,
          protein: 0,
          iron: '2%',
        },
        {
          name: 'Honeyb',
          calories: 408,
          fat: 3.2,
          carbs: 87,
          protein: 6.5,
          iron: '45%',
        },
        {
          name: 'Donut',
          calories: 452,
          fat: 25.0,
          carbs: 51,
          protein: 4.9,
          iron: '22%',
        },
        {
          name: 'KitKat',
          calories: 518,
          fat: 26.0,
          carbs: 65,
          protein: 7,
          iron: '6%',
        },
      ],
    }
  },
  methods: {
    getdata() {
      console.log(this.desserts[0].protein);
    }
  },
})

The solution is that you need to do a deep copy of the customer.items before using map to add the new object property.

initialize() {
  let items = JSON.parse(JSON.stringify(this.customer.items))
  items.map(item => {
    item.quantity = '5'
    return item
  })
  this.items = items
}

本文标签: javascriptVuetify text field in data table item slotStack Overflow