Conditionally Prevent Checkbox Change

I cannot for the life of me figure this out.
I’ve added a fiddle at:

I want a user to click a checkbox and in some states, have it update v-model as normal
But in other states check or uncheck based on some other calculations. This is not my design :slight_smile:

I’ve tried:

  1. Using a v-model with a set / get
  2. Imitating a v-model using @change.prevent and :checked
  3. Assuming the change happens after the click (which i think is wrong) and using @click.prevent with :checked

I can get the model to react appropriately, but when I do, the state of the DOM checkbox itself seems to toggle independently of the :checked attribute.

Is there a best practice for accomplishing this by any chance?

Thank you

The change and input events cannot be cancelled, it is also confusing to try and handle it like this.

I would suggest setting disabled on the checkbox when the user is not allowed to interact with it. You could use CSS to have it ignore pointer events but I’m not sure that’s much better than trying to ignore the change as you are trying to do.

P.S. It is possible just a bit nasty and $nextTick does not appear to like the idea.

Yes. Unfortunately I’m simplifying the ux here. Disabling it with CSS wont work. I actually need to calculate whether it’s true or false and put that in

so you use Vue
v-bind is a way make it and for easier and more effective

I’ve solved the problem at:

As far as I can tell, the click event is triggered even by keyboard events (src)

And happens before the @change or @input events (src)

So you can click.prevent the event, but you need to either prevent it selectively or retrigger the event after the calculation.

//HTML Template            
<input :checked="calculatedValue5" @click="correctAnswer" type="checkbox">

//VUE component

data() {
	return {
      calculatedValue5: false,

methods: {
			const newDomValue =;
            this.calculatedValue5 = this._calculateNewValue(newDomValue);
            if(this.calculatedValue5 !== newDomValue){

I think this is preventing checkbox value from updating before the data value, which seems to break the reactivity. I’m not sure the technical reason why, but the demo does work. If anyone wants to correct my misunderstandings of what’s going on under the hood OR why a this.$forceUpdate() doesn’t get things back in sync I would love to know.

I know this is a little late to the party, but maybe this will be helpful to others. Simply disabling a checkbox either programmatically or using the disabled attribute can be confusing to a user. The first gives no indication at all as to why the checkbox isn’t working; the second removes the input from the focus order, which means that someone using a screen reader won’t be able to tab into it. So in addition to using preventDefault(), a good solution is to set an aria-disabled=“true” attribute on the input and change the appearance; e.g, lighter coloring (maintaining enough contrast), text-decoration: line-through.