How to cancel a v-model change event on select element in Vue 3

Prevent v-model value from updating
tagged:

vue

Sometimes you need to prevent a change from happening, or cancel the execution of a potential change.

In my case, I had a <select> dropdown, and by a certain criteria, the user was alerted (by a confirm dialog) about a destructive change to data.

If the user clicked cancel, I would obviously like to cancel the v-model change of the value. So here’s how:

<script setup lang="ts">
import { watch, ref } from 'vue';

// My variable which I want to keep track of or "revert" in case of cancel
const selectedTemplate = ref('');

// Store the previous value in a ref
const oldTemplateValue = ref('');

// Watch for changes to the v-model variable
watch(selectedTemplate, async(newValue, oldValue) => {
  oldTemplateValue.value = oldValue;
});

function applyTemplate(e) {
  const okToContinue = confirm('This change will overwrite the previously applied template. Continue?');
  if (!okToContinue) {
    e.preventDefault();
    selectedTemplate.value = oldTemplateValue.value; // Restore previos value
    return;
  }
  // …go ahead with the change
}
</script>

<template>
  <select v-model.lazy="selectedTemplate" @change="applyTemplate">
    <option value="" disabled>Choose template</option>
    <option v-for="template in templates" :key="template.templateName" :value="template.templateName">
      {{ template.templateName }}
    </option>
  </select>
</template>