Vue change object in array and trigger reactivity

前端 未结 3 996
挽巷
挽巷 2021-02-07 02:36

How can I trigger an update when altering part of an object found by index in an array?

The docs show how to alter the value of an array:



        
相关标签:
3条回答
  • 2021-02-07 03:15

    Here is another demo example that I think give a good illustration of the reactivity of objects inside an array. Try it live here: https://codepen.io/antoniandre/pen/ZdjwKG

    JS

    new Vue({
      el: "#app",
      data: {
        array: []
      },
    
      methods: {
        addTimeProp() {
          this.array.forEach(item => {
            this.$set(item, 'time', null)
          })
        },
        updateTimeProp() {
          this.array.forEach(item => {
            item.time = (new Date()).toString()
          })
        }
      },
    
      created () {
        this.array.push({ name: 'today' }, { name: 'tomorrow' })
      }
    })
    

    HTML: PUG

    #app
      h1 Reactivity of objects inside an array
      h2 Content of the array
      pre {{ array }}
      button(@click="array.push({ name: 'another day' })") Add another object
      button(@click="addTimeProp") Add `time` property
      button(@click="updateTimeProp") Update `time` property
    
    0 讨论(0)
  • 2021-02-07 03:28

    As long as you call set() once to set the object (with the property you are going to update) in the array, Vue will react to changes in the object's properties. Here's an example that has one array of objects initialized in our app's data, and another array of objects manually set (with Vue.set()) when mounted. Clicking the button updates a property on one object in each of those arrays, and Vue reacts. Note that the set() call that happens in mount() could really happen anytime.

    https://codepen.io/jordan-kalosal/pen/VrwjoR

    new Vue({
      el: "#app",
      data: {
        arr: [
          {
            property: 'OBJ1 Prop'
          },
          {
            property: 'OBJ2 Prop'
          }
        ],
        setLater: false
      },
      mounted() {
        this.$set(this, 'setLater', [
          {
            property: 'setLater OBJ1 Prop'
          },
          {
            property: 'setLater OBJ2 Prop'
          }
        ])
      },
      methods: {
        _updateObjProps() {
          this.arr[0].property = (new Date()).toString();
          this.setLater[0].property = (new Date()).toString();
        }
      }
    })
    
    0 讨论(0)
  • 2021-02-07 03:28

    You could update the sub-property in the array element with this.$set(). For example, to increment an x subproperty in the first two array elements (creating the sub-property if it doesn't exist):

    methods: {
      update() {
        this.$set(this.arr[0].foo, 'x', (this.arr[0].foo.x || 0) + 100)
        this.$set(this.arr[1].foo, 'x', (this.arr[1].foo.x || 0) + 100)
      }
    }
    

    new Vue({
      el: '#app',
      data() {
        return {
          arr: [
            {
              foo: {
                x: 100,
                y: 200
              }
            },
            {
              foo: {
                /* x does not exist here initially */
                y: 400
              }
            }
          ]
        };
      },
    
      methods: {
        update() {
          this.$set(this.arr[0].foo, 'x', (this.arr[0].foo.x || 0) + 100)
          this.$set(this.arr[1].foo, 'x', (this.arr[1].foo.x || 0) + 100)
        }
      }
    })
    <script src="https://unpkg.com/vue@2.6.10/dist/vue.min.js"></script>
    
    <div id="app">
      <button @click="update">Update</button>
      <p>arr[0]: {{ arr[0] }}</p>
      <p>arr[1]: {{ arr[1] }}</p>
    </div>

    codepen

    0 讨论(0)
提交回复
热议问题