Web

Vue 3: Deselect All Options in Multiple Selects

Learn how to programmatically deselect all options across multiple Vue 3 select elements on button click using v-model reactivity, template refs, or form reset. Pure Vue 3 solutions without jQuery for efficient form resets.

1 answer 1 view

Vue 3: How to programmatically deselect all selected options across multiple select elements in a form on button click?

I have a form with several <select> inputs and need to unselect all currently selected options when a button is clicked, similar to jQuery’s $("option:selected").removeAttr("selected");.

Current code:

vue
<template>
 <form id="myform">
 <select @change="clearOptions($event)" id="mySelect">
 <option>Pineapple</option>
 <option>Banana</option>
 </select>

 <select @change="clearOptions($event)" id="mySelectTwo">
 <option>Apple</option>
 <option>Orange</option>
 </select>
 </form>
</template>

<script setup>
const clearOptions = (e) => {
 e.preventDefault();
 // Need pure Vue 3 solution to deselect all options without jQuery
};
</script>

What is the recommended Vue 3 way (using reactivity, refs, or DOM manipulation) to achieve this?

In Vue 3, the cleanest way to programmatically deselect all selected options across multiple select elements in a form on button click is through reactive v-model bindings—set each vue 3 select’s value to null or an empty string via refs. This beats jQuery’s removeAttr("selected") by leveraging Vue 3 reactivity for instant UI updates without DOM hacks. Add a reset button that loops through your model refs, and you’re done—no @change misuse needed.


Contents


Understanding Vue 3 Select Reset

Ever clicked a reset button in a form and watched selections stubbornly hang on? That’s the pain your current code hits—@change on selects won’t trigger from a button, and jQuery feels like a relic in Vue 3. The fix? Vue’s reactivity system shines here. Native HTML select elements ignore selected attributes once Vue mounts (it prioritizes v-model), so you control them via JavaScript refs or bindings.

Why multiple methods? Reactive v-model is declarative and scales effortlessly for vue 3 reset form scenarios. Refs offer direct DOM control for edge cases, like when you skip v-model. And form-level resets handle bulk ops natively. Pick based on your setup: if you’re already modeling form data (smart move), go reactive. Otherwise, refs get gritty but work.

Your code’s close—just swap @change for a button’s @click, bind models, and reset. Let’s build it step by step.


Method 1: Reactive Reset with v-model

This is the Vue 3 way: bind each vue 3 select to a reactive ref, then null them out on click. It’s reactive, so the DOM updates instantly—no manual option fiddling.

Start with refs for your values. For single selects, use ref(null) or ref(''). Add a placeholder option like <option value="">Select...</option> to show “cleared” visually.

Here’s your form, refactored:

vue
<template>
 <form id="myform">
 <select v-model="select1" id="mySelect">
 <option value="">Select fruit</option>
 <option value="pineapple">Pineapple</option>
 <option value="banana">Banana</option>
 </select>

 <select v-model="select2" id="mySelectTwo">
 <option value="">Select fruit</option>
 <option value="apple">Apple</option>
 <option value="orange">Orange</option>
 </select>

 <button type="button" @click="resetForm">Reset All</button>
 </form>
</template>

<script setup>
import { ref } from 'vue'

const select1 = ref(null)
const select2 = ref(null)

const resetForm = () => {
 select1.value = null
 select2.value = null
}
</script>

Boom—click resets both. Why null over ''? Matches non-string values perfectly; use '' if your options are strings. As the Vue.js Forms documentation notes, “For unbound selects, Vue ignores the selected attribute and treats it as unselected.”

Scale to more? Object of refs:

js
const formData = ref({
 select1: null,
 select2: null
})

const resetForm = () => {
 Object.keys(formData.value).forEach(key => {
 formData.value[key] = null
 })
}

No watchers needed. Reactive magic.


Method 2: Template Refs and DOM Manipulation

Skip v-model? Use template refs for direct access, then selectedIndex = -1 on each element. Perfect for vue 3 programmatically clear select without models, or legacy forms.

Ref an array for multiples: ref="selects". Vue collects them automatically.

Updated template:

vue
<template>
 <form id="myform">
 <select ref="selects" id="mySelect">
 <option>Pineapple</option>
 <option selected>Banana</option> <!-- Vue ignores this -->
 </select>

 <select ref="selects" id="mySelectTwo">
 <option>Apple</option>
 <option selected>Orange</option>
 </select>

 <button type="button" @click="resetSelects">Reset All</button>
 </form>
</template>

<script setup>
import { ref, nextTick } from 'vue'

const selects = ref([])

const resetSelects = async () => {
 await nextTick() // Ensures DOM ready
 selects.value.forEach(select => {
 select.selectedIndex = -1
 })
}
</script>

selectedIndex = -1 deselects everything—works for single or multi-selects, per MDN’s HTMLSelectElement docs. Why nextTick? Button clicks can race DOM updates.

This mirrors your jQuery intent but Vue-native. Tradeoff: less reactive than v-model (no auto-tracking changes).


Method 3: Form-Wide Reset with Native API

For vue 3 form reset button across dozens of inputs? Grab the form ref and call reset(). It reverts to initial value attrs—but selects need careful setup.

Template tweak:

vue
<template>
 <form ref="formRef" id="myform">
 <select id="mySelect">
 <option value="">--</option> <!-- Initial empty -->
 <option value="pineapple">Pineapple</option>
 <option value="banana">Banana</option>
 </select>
 <!-- Same for mySelectTwo -->
 <button type="button" @click="resetFormNative">Reset</button>
 </form>
</template>

<script setup>
import { ref } from 'vue'

const formRef = ref(null)

const resetFormNative = () => {
 formRef.value.reset()
}
</script>

Simple! But requires empty initial options. Combine with v-model for hybrid power. The Vue template refs guide backs this for bulk DOM ops.

Quick comparison:

Method Pros Cons Best For
v-model Reactive, declarative, tracks values Needs per-select refs Modeled forms
Template Refs Direct control, no models Imperative, nextTick boilerplate Quick DOM tweaks
Form Reset Zero loops, native Relies on HTML defaults Simple forms

Handling Multiple Selects and Edge Cases

What about <select multiple>? v-model uses arrays: ref([]), reset to [].

js
const multiSelect = ref([])
const resetMulti = () => { multiSelect.value = [] }

Dynamic forms? Watch selects.value.length or use computed. Button outside form? No issue—refs are global.

Edge cases bite: Async options loading? Reset post-load with onMounted + nextTick. Multi-select partial clears? Loop options and set selected = false, but selectedIndex = -1 handles it.

From community fixes like this Stack Overflow thread, watchers help dynamic resets:

js
import { watch } from 'vue'
watch(() => someCondition.value, () => {
 select1.value = null
})

Your @change? Ditch it—buttons use @click.


Best Practices and Common Pitfalls

Favor v-model—it’s Vue 3’s heart. Avoid option loops; null/ selectedIndex=-1 is faster. Pitfall: No placeholder? Reset looks “selected” (empty option stays). Fix: Always add <option value="">.

Vue 2 vs 3? Options API used $refs; Composition API refs are cleaner. Third-party like vue-multiselect? Overkill—stick native for vue 3 clear select options.

Test: Mount, select, click. No change? Console select.value—timing issue, add nextTick. Mobile? Selects behave identically.

Pro tip: Expose reset via composable for reusability.

js
// composables/useFormReset.js
import { ref, nextTick } from 'vue'
export function useFormReset(selects) {
 const reset = async () => {
 await nextTick()
 selects.value.forEach(s => s.selectedIndex = -1)
 }
 return { reset }
}

Here’s where it gets flexible.


Sources

  1. Vue.js Forms — Official guide on v-model for selects and form resets: https://vuejs.org/guide/essentials/forms.html
  2. Vue.js Template Refs — Documentation for accessing DOM elements like select refs: https://vuejs.org/guide/essentials/template-refs.html
  3. MDN HTMLSelectElement.selectedIndex — Native API for deselecting options programmatically: https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/selectedIndex
  4. Stack Overflow: Reset Select in Vue.js — Community solutions for v-model null resets: https://stackoverflow.com/questions/52114570/how-to-reset-select-drop-down-in-vuejs
  5. Stack Overflow: Clear v-model on Select Change — Handling dynamic clears with watchers: https://stackoverflow.com/questions/51530477/how-to-clear-v-model-used-with-a-select-when-options-change

Conclusion

Vue 3 makes vue 3 deselect all options trivial—v-model refs win for reactivity, refs/DOM for control, form reset for simplicity. Ditch jQuery; your form now resets smoothly on any button click. Scale it, test edges, and forms feel alive. Grab the code, tweak, deploy.

Authors
Verified by moderation
NeuroAnswers
Moderation
Vue 3: Deselect All Options in Multiple Selects