Hi,
I am using vuejs 2.0.1 and I want to create a component that looks like this:
<vue-checkbox v-model="page.ads_able"></vue-checkbox>
As from the api page that v-model is a syntactic sugar combinding :value
and @input
.
So I write a template with a props name value and a method for input event like this:
...
<input type="checkbox" :value="value" @input="onInput" />
...
...
props: {
value: {},
},
methods: {
onInput(event) {
this.$emit('input', event.target.value)
}
}
...
But it doesn't work. I don't know if there any special care about checked attribute of the checkbox. I tried the exact same thing with <select>
and it's worked as aspect though. Any suggestion?
Well, I think I find a solution to my own question.
I need to set a data variable to accept value from props and change that data at the corresponding event then emit the input event so that v-model can handle the value change. Something along these lines:
template
<input type="checkbox"
value="1"
:checked="checked"
@change="change"
/>
And in javascript:
data: function() {
return {
checked: this.value
};
},
props: ['value'],
methods: {
change: function() {
this.checked = !this.checked;
this.$emit('input', this.checked);
}
}
That's work now. :D
@phatchai Here is a work around for the issue.
https://jsfiddle.net/cv2tL9oy/
Issues are for bugs and feature requests only. Please use forum.vuejs.org or Gitter.
@phatchai Your example works not correctly. When we change parent model - yours checkbox component wouldn't change.
We need to take checked from props and emit event 'input' onChange, and don't store local state.
Here is my example:
<template>
<input type="checkbox" :checked="value" @change="changeHandler">
</template>
<script>
export default {
name: 'v-switch',
props: ['value'],
methods: {
changeHandler () {
this.$emit('input', !this.value)
}
}
}
</script>
There needs to be better documentation on v-model. Everywhere I look says it's just a shorthand for :input="$emit('input', event.target.value)" but this issue proves otherwise. The bug here is lack of documentation.
Don't use any of the other examples here! They are broken!
Here's the solution: use $event.target.checked, not $event.target.value!
@myxibrium solution didn't work to me but this did (changing :value
for :checked
):
<template>
<input type="checkbox" :checked="value" @input="$emit('input', $event.target.checked)" />
</template>
<script>
export default {
props: ['value']
};
</script>
I can also bind a group of checkboxes to an array. The array will then contain a list of the values of the checked checkboxes, see 2nd example in the documentation https://vuejs.org/v2/guide/forms.html#Checkbox
How to wrap a checkbox _correctly_ so that this behavior will also be preserved?
I can also bind a group of checkboxes to an array. The array will then contain a list of the values of the checked checkboxes, see 2nd example in the documentation https://vuejs.org/v2/guide/forms.html#Checkbox
How to wrap a checkbox _correctly_ so that this behavior will also be preserved?
https://vuejs.org/v2/api/#model
Use a custom model prop and event. Eg.
model: {
prop: 'modelValue',
event: 'change'
}
Bind the @change
to the checkbox and $emit the value differently based on whether the v-model value (this.modelValue
) is an array (multiple checkboxes) or not (single checkbox).
@vincesp I managed to solve this by using @rjoo 's answer and a bit of array checking when the box change.
methods: {
change() {
const checked = this.checked.slice();
const found = checked.indexOf(this.value);
if (found !== -1) {
checked.splice(found, 1);
} else {
checked.push(this.value);
}
this.$emit("change", checked);
}
}
};
codesandbox here: https://codesandbox.io/s/5x0296z7jp
I didn't put handling of single select boxes in there, but that's fairly trivial to do. Hope it helps.
Sorry for beign late. I came up with this solution, what do you guys think?
Vue.component("v-check", {
template: `
<input type="checkbox" :value="value" v-model="proxyChecked" />
`,
model: {
prop: "checked",
event: "change",
},
props: {
checked: {
type: [Array, Boolean],
default: false,
},
value: {
default: null,
},
},
computed: {
proxyChecked: {
get() {
return this.checked;
},
set(val) {
this.$emit("change", val);
},
},
},
});
Code demo here: https://jsfiddle.net/ariel0196/euzn79gc/3/
Most helpful comment
Well, I think I find a solution to my own question.
I need to set a data variable to accept value from props and change that data at the corresponding event then emit the input event so that v-model can handle the value change. Something along these lines:
template
And in javascript:
That's work now. :D