简体   繁体   中英

How to pass a prop in to a child component on click - Vue2

Idea behind the code is to make a child component active, when i click on it in a parent vue.

Parent vue file:

<PackageItem
  v-for="pack in packagesData"
  :key="pack.id"
  @click.native="selectPackageItem(pack.id, pack.humanLabel, pack.humanPrice, pack.index)"
>

Child component:

props: {
  selected: Boolean
},

data () {
  return {
    selected: selected
  }
},

How can i send selected prop on click to a child component? If i set it this way:

<PackageItem
  :selected="true"
  @click.native="selectPackageItem(pack.id, pack.humanLabel, pack.humanPrice, pack.index)"
>

It would make all items selected to true , i want to set it on click only.

You can do like:

<PackageItem
  v-for="pack in packagesData"
  :key="pack.id"
  @click.native="
    selectPackageItem(pack.id, pack.humanLabel, pack.humanPrice, pack.index)"
  :selected="selected[pack.id]"
>

Where selectedPackageItem method will set the selected package:

selectPackageItem(packId, packLabel, packPrice, packIndex) {
    this.$set('selected', packId, true)

Or, if you want to toggle between true and false on click:

this.$set('selected', packId, !this.selected[packId])

In the data option, you should just have:

selected: []

Also, in your child component the following code is not required:

/* REMOVE
 data () {
   return {
     selected: selected
   }
 },
*/

When you want to use selected props inside script, you just need to use this.selected and inside the template just use selected .

You can control the selection from the parent component by defining an array to store selected ids and a function to check selection.

data(){
    return {
        ...
        selected: []
    }
},
methods: {
    isSelected(id){
        return this.selected.indexOf(id) > -1;
    }
}

Then in your click method, push the id of the clicked item.

// Stub for `selectPackageItem` method
if(this.isSelected(id)){
    // Maybe unselect?
} else {
    this.selected.push(id);
}

Now you template becomes:-

<PackageItem v-for="pack in packagesData" :selected="isSelected(pack.id)" :key="pack.id" @click.native="selectPackageItem(pack.id, pack.humanLabel, pack.humanPrice, pack.index)">

I ended up with a more elegant solution:

<PackageItem
  v-for="pack in packagesData"
  :key="pack.id"
  :selected="selectedPackages(pack.index)"
  @click.native="selectPackageItem(pack.id, pack.humanLabel, pack.humanPrice, pack.index)"
>

Then added a method to check selected packages in an array:

selectedPackages (index) {
  let packages = this.packages
  let selected = packages.some(p => p.index === index)
  return selected
}

selectedPackages returns a boolean value. this.packages is an array with active packages (clicked), that contains a lot of information besides ID and index . With .some i am getting true or false value, if clicked item's index is exact the same with the one in array ( this.packages ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM