0

I'm trying to push a new item to an array however the DOM is not updating. I've read the Vue docs which say use Vue.set to enable reactivity for adding objects to an array. https://jsfiddle.net/exL27gvz/40/

    Vue.component('team-invite-list', ({
    template: '<div class="mt-2 flex"><a v-for="user in invitedUsers" :key="user.test" href="#">test</a></div>',
    props: ['invitedUsers'],
    methods: {
        addInvitedUser: function(user) {
            Vue.set(this.invitedUsers, this.invitedUsers.length, user)
        }
    },
    mounted() {
            console.log(this.invitedUsers)
      this.invitedUsers.push({test: '2'})
    }
}));

var vm = new Vue({
    data() {
    return {
    };
  },
  mounted() {

  }
}).$mount('#app');



<div id="app">
  <team-invite-list :invited-users="[{test: 'test'}]"></team-invite-list>
</div>

The DOM only ever shows the value object passed in as a prop.

4
  • 1
    Don't try to mutate props Commented Sep 19, 2020 at 14:16
  • Thanks Dan that has resolved my problem. If you post it as an answer I can mark it as the right answer. Commented Sep 19, 2020 at 14:28
  • @Paradigm did you see my answer? Commented Sep 19, 2020 at 14:35
  • Sorry @Dan I've just marked as valid. Commented Oct 21, 2020 at 9:27

2 Answers 2

1

Don't try to mutate props. Here's some explanation from the docs:

All props form a one-way-down binding between the child property and the parent... This prevents child components from accidentally mutating the parent’s state, which can make your app’s data flow harder to understand. In addition, every time the parent component is updated, all props in the child component will be refreshed with the latest value. This means you should not attempt to mutate a prop inside a child component.

If you find yourself wanting to mutate a prop, there are several options. Here are two common ones:

Vuex

Many times props aren't ideal when you can use a global store for state management. It can take the hassle out of sharing data among components. Each component can get and set data directly from the store, and this decouples components and can greatly simplify your design. If you're trying to pass around an array of app data, this is a good sign that you should be using Vuex.

Clone / Emit

If the two components always appear together, or it simply makes more sense to maintain the parent/child relationship, then keep the prop but emit changes back to the parent. You can clone the prop in the child if necessary, mutate the clone, and then emit that back.

Sign up to request clarification or add additional context in comments.

Comments

0

You could not update the prop inside the child component, you should emit an event from the child one to the parent one in order to update that property inside the parent component :

 mounted() {
            console.log(this.invitedUsers)
          this.$emit("push-invite",{test: '2'})
    }

in parent component add @push-invite="pushInvite" :

var vm = new Vue({
    data() {
    return {
    invitedUsers:[{test: 'test'}]
    };
  },
  methods:{
    pushInvite(invite){
      this.invitedUsers.push(invite)
    }
  },
  mounted() {

  }
}).$mount('#app');



<div id="app">
  <team-invite-list :invited-users="invitedUsers" @push-invite="pushInvite"></team-invite-list>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.