vue: Checkbox doesn't check with binding checked attribute
Version
2.3.3
Reproduction link
http://jsfiddle.net/yMv7y/2617/
Steps to reproduce
Instead of using v-model
on the native checkbox, simply use :checked="computedProp"
to manage the checkbox’s checked
state and block UI-checking (mouse-click, and tab-space-ing) by doing e.preventDefault()
on click
.
What is expected?
For the checkbox to check.
What is actually happening?
The checkbox is not checking, despite that the computed property is evaluating to true
.
I don’t want to use v-model
because, from what I understand, v-model
is short for something like :checked="foo"
and @change="val => { foo = val }"
(the exact logic found here), and since I am making a minimal Checkbox component only to wrap the native checkbox with some elaborate CSS, I’d like to refrain from having to maintain any “data” props, and instead of the event handler v-model
comes with, I’d like to simply hoist the event up.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 8
- Comments: 17 (5 by maintainers)
You never set
this.checked
to a value. So the checkbox won’t update. Besides, do yourself a favor and usev-model
. It’s much easier, even for wrapped components. That doesn’t stop the component from implementing av-model
interface itself or customizing the model.This is an implementation that works: http://jsfiddle.net/t08v9ny6/3/
This is still an issue for me, I still don’t see why doing something along the lines of
<input type="checkbox" :checked="someBooleanValue">
wouldn’t work properly? I don’t want to be using v-model since I also want the boolean toggle to occur programatically when clicking on the parent element of the input element.Looks like the behavior is caused by the
e.preventDefault()
call. My assumption is that this is because Vue’s DOM update kicks in via a microtask before the browser checks forpreventDefault
behavior - the browser resets the checkbox state when it sees that the event default behavior has been prevented, overwriting the DOM changes made by Vue.In Firefox this works properly, so I think this is a Chrome/Webkit-only behavior.
I’m not sure why you need
e.preventDefault()
here, but if you really need it, you can wrap the$emit
calls in asetTimeout
to get around this: http://jsfiddle.net/yMv7y/2621/This is very confusing, how do we use binding on a checkbox? v-model doesn’t work on the input element from within a child components for some reason??
Same happens on
<input type="radio" />
elements.<input type="checkbox" :checked="checked" :data-wug="checked"/>
renders to<input type="checkbox" data-wug="true"/>
and not<input type="checkbox" checked data-wug="true"/>
as expected.@yyx990803 - thank you for that example! I have had a lot of trouble with this in Vuex -
e.preventDefault()
throws the whole thing out of whack.What I was going for was only actually toggling the checkbox if a Vuex action (and mutation) were successful. So basically, even if a user checked a checkbox - that doesn’t mean I want it to go to a checked state - I just want it to keep following its computed property it was already set to using
:checked
. And because usingv-model
in Vuex isn’t a good idea, I found that the UI was getting toggled even though I hadn’t committed a mutation. I found this strange. In further research, I actually found there wasn’t a good answer to this question. I couldn’t believe it - as I believed this to be a common pattern - not wanting a checkbox to toggle until some action is complete - that way you can deal with an error and not end up toggling the checkbox - say, for like a user’s preferences page.Nothing worked until doing something like your setTimeout example. Thank you, and thank you @hirokiosame for asking this question.