0
votes

enter image description hereQuick Context:

I have a parent Parent.vue that feeds the same list

[{key: "one", selected: false], {key: "two", selected: false}, {key: "three", selected: false]

to multiple components one the same page. None of the items in the list can be selected twice.

What I have tried:

So my parent creates a Child.vue component and passes in this list. Child.vue props accepts it then populates the :items fields of the <v-select>. As a result we see all 3 items. I select "two". I bind to change event so I $emit to parent the key ("two") and the flag (selected: true) so the parent filters out the list so there is only "one" and "three" now. If I were to add another component at this point - all fine - it would only have "one" and "three" to select from. My problem is that when I select this "two" item - it disappears. Primarily because the parent takes this item out. But... how to I make it so it either stays (indicating that this item have been selected) and other components are not able to select it no more? Can I possible disable just this "two" item for selection (in case other components try to select it - they can't).

I can do it easily with plain HTML and JS - with Vue / Vuetify - how can I accomplish that?

2
The way I am doing it (removing the item by setting one of the element to selected: true) does the job as far as multiple components are not able to select it. The problem is that original component does not save it - it just clears it. I have the value but visual disappears. I want the visual to stay - then I am all set. Alternative is to may be somehow disable this item "two" so it is in the list but you can no longer select it. Can you do something like <v-list-item v-for... disabled (if selected = true)Alexey Shevelyov

2 Answers

0
votes

You can do this by adding a property called disabled to your item and compute the value of that property based on the selection of other items:

get filteredItems() {
    return this.items.map((item) => 
      id: item.identifier, // replace this with the items identifier
      text: item.text_value, // replace this with your items display text
      disabled: this.items.filter((item) => [...this.firstSelection,...this.secondSelection].filter((selection) => selection === item).length > 0)
      // ^ replace the above destructured array params with your real v-model bindings
      // if the v-models bindings aren't arrays (and the select isn't multiple)
      // then there is no reason to destructure that value
    })
}

Now modify your v-select component and add a value for the item-disabled property that matches the key that we can lookup in the map:

<v-select :items="filteredItems" item-text="text" item-id="id" item-disabled="disabled"
0
votes

So what I ended up doing is binding to :item-disabled property- I bind selected to and maintain it from the parent throughout all the child components. It get deselected - I emit the event to the parent saying hey element by id "this" is no longer selected. That in turn refreshes it for all the components that are getting this list through props. Ohgodwhy has a pretty similar solution (thanks!).