-
-
Notifications
You must be signed in to change notification settings - Fork 33.8k
Description
What problem does this feature solve?
Consider the <input>
element. It maintains its own internal state for its value (by the browser) irrespective of whether or not it is being driven by v-model
.
After looking at some Vue component libraries, most of the components externalize their state through props, meaning that the parent component must define the value for that component in its data and use v-model
to wire it up -- the component cannot be used without v-model
because it doesn't maintain the state internally to the component.
Ideally I'd like to author input components that satisfy the following requirements:
- Can be used without
v-model
(the component maintains the state itself) - Can be used with
v-model
(the state is driven entirely by the prop emittinginput
events)
This results in somewhat messy code like this:
Vue.component('checkbox', {
template: '<div class="checkbox" @click="toggle">{{ internalValue ? "Checked" : "Unchecked" }}</div>',
props: {
value: {
type: Boolean,
default: false,
},
},
data() {
return {
internalValue: false,
};
},
watch: {
value: {
immediate: true,
handler(value) {
this.internalValue = value;
},
},
internalValue(internalValue) {
this.$emit('input', internalValue);
},
},
methods: {
toggle() {
this.internalValue = !this.internalValue;
},
},
});
In order to distinguish between the prop and the data, I've used value
and internalValue
respectively. The problem is that value
is rarely used in the code (it's only used in the watcher) and I have to remember to use internalValue
throughout the component's code and template instead of value
(since internalValue
is the mutable source of truth).
To avoid this, I could instead name the prop externalValue
and the data value
, but now I would have to use <checkbox :external-value="x">
which is not ideal (the external prop should be called simply "value").
I'm proposing a feature in which you can specify what internal name a prop should be exposed as within the component without changing the external name of that prop in templates (kind of like how method arguments work in objective-c).
What does the proposed API look like?
Vue.component('foo', {
props: {
value: {
internalName: 'valueProp',
},
},
template: '<div>{{ valueProp }}</div>',
});
<foo value="bar">