Vue Multiselect多选模式下选中时移除不同分组选项的实现问题
I get exactly what you're trying to do here—you want to let users select multiple options from the same group, but automatically remove any selected options from other groups when a new cross-group option is picked. The problem with your original select event approach is that Vue-Multiselect’s internal logic overrides your filtered values right after you modify them. Let’s fix that.
Why Your Initial Approach Failed
The select event fires before the component finishes updating the v-model bound values array. When you filter this.values in the event, the component immediately adds the newly selected option back in, undoing your work. We need to hook into a point where we can fully control the final state of values.
Solution 1: Watch the values Array
Use a watcher to react to changes in values, then filter out any cross-group options after the component updates the array:
<template> <multiselect v-model="values" :options="options" :multiple="true" label="name" track-by="name" ></multiselect> </template> <script> import Multiselect from 'vue-multiselect'; export default { components: { Multiselect }, data() { return { values: [], options: [ { name: "Option 1", group: 1 }, { name: "Option 2", group: 1 }, { name: "Option 3", group: 2 }, ] }; }, watch: { values(newValues) { if (newValues.length === 0) return; // Grab the group of the most recently selected option const activeGroup = newValues[newValues.length - 1].group; // Filter to keep only options from this group this.values = newValues.filter(item => item.group === activeGroup); } } }; </script>
This works because the watcher triggers after values has been updated by the component. It ensures only options from the same group as the latest selection stay in the array.
Solution 2: Use the input Event
The input event returns the full array of currently selected options. We can modify this array directly and assign it back to values, overriding the component’s default behavior:
<template> <multiselect v-model="values" :options="options" :multiple="true" label="name" track-by="name" @input="handleSelection" ></multiselect> </template> <script> import Multiselect from 'vue-multiselect'; export default { components: { Multiselect }, data() { return { values: [], options: [ { name: "Option 1", group: 1 }, { name: "Option 2", group: 1 }, { name: "Option 3", group: 2 }, ] }; }, methods: { handleSelection(selectedOptions) { if (selectedOptions.length === 0) { this.values = []; return; } // Use the group of the last selected option as the active group const activeGroup = selectedOptions[selectedOptions.length - 1].group; // Filter and update the values array this.values = selectedOptions.filter(item => item.group === activeGroup); } } }; </script>
This approach intercepts the selection state before it’s finalized, so your filtered array becomes the source of truth right away.
Key Notes
- Both methods preserve the order of selected options within the same group.
- If a user deselects an option, the remaining options from the same group stay intact (which aligns with your requirements).
内容的提问来源于stack exchange,提问作者Pierre de LESPINAY

