headlessui
headlessui copied to clipboard
Vue ComboboxOption `selected` Not Updated
What package within Headless UI are you using? @headlessui/vue
What version of that package are you using? v1.6.5
What browser are you using? Chrome
Reproduction URL https://codesandbox.io/s/headless-combobox-cih5y9
Describe your issue
The selected
slot property isn't being updated when the model is updated outside of the component. In the example there's an additional list with buttons to remove items by index. It properly removes them from the value as shown in pre output, but the selected
attribute doesn't update and items incorrectly stay marked as selected.
The bug only occurs when the static option is true in ComboboxOptions
.
Solution
You can fix it adding :key="selectedPeople.length"
in ComboboxOptions
.
That way you force the component to re-render when the amount of elements changes.
Reproduction URL: https://codesandbox.io/s/headless-combobox-forked-6dp0y6?file=/src/components/ComboBox.vue:125-140
Hey! Thank you for your bug report! Much appreciated! 🙏
This is interesting, I think that somehow this might be a Vue bug where the mutation using splice
doesn't give you the wanted result. The workaround provided by @EvertonWingert seems to work, and looking at your original CodeSandbox it seems like you already implemented that.
The reason why I think it is a Vue bug is because if you replace the splice
with this:
- selectedPeople.value.splice(idx, 1);
+ selectedPeople.value = selectedPeople.value.filter((_, i) => i !== idx);
It totally works, which makes me think that this is a bug in the reactivity / watching / proxy implementation within Vue.
I think it might be looking for "assigments" (via Proxy setters), because if you do this:
selectedPeople.value.splice(idx, 1);
+ selectedPeople.value = selectedPeople.value.slice();
It also totally works!