Search code examples
vue.jscomponentsparent-childv-forvue-props

How to update Vue array of components with a click IN one of the children components


I am displaying an array of child components and in the child component, I need to click some text to make THIS child push to the front of the array. I've tried it where the child sees the array which doesn't seem to be of any help. And now I've tried to emit with an event to the parent component and I still can't seem to figure out how to push any of the child components to the beginning of the loop with a click IN the child component.

Parent component and method:

 <location-item v-for="(location, index) in results"
                       :key="location.Id"
                       :index="index"
                       :location="location"
                        @changeLocation="changeLocation(location, $event)" />

methods(): {
      changeLocation(location, newIndex) {
           location.index = newIndex;
    },
}

Child components's clickable text and method

<a @click="changeCurrent">
   Change Location
</a>

methods: {
      changeCurrent() {
        this.$emit('changeLocation', this.newIndex);
      }
},

So when it's clicked in the child component, it throws THAT child component to the beginning of the v-for loop. The suggestion I'm giving is the closest I feel I've gotten, yet, it does nothing. I haven't seen anyone online really seem to do this so I figured I'd come to ask here.


Solution

  • This is very much a JavaScript question. You are on the right track with the emit from child to parent, need to do some javascript using splice().

    As you are already passing the index of the child component, to the component, that is the only thing we need to pass to parent, so...

    Child:

    props: {
      location: String,
      index: Number,
    },
    methods: {
      changeCurrent() { // pass the childs index to parent
        this.$emit("change-location", this.index);
      },
    },
    

    Then in parent changeLocation function we use the index to reorder array:

    changeLocation(index) {
      let item = this.results.splice(index, 1); // remove item from array
      this.results.splice(0, 0, item[0]); // put item first in array
    },
    

    Here is a DEMO for you. You can also use unshift to add the item.