Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Props can be provided with a setter. #175

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
112 changes: 112 additions & 0 deletions active-rfcs/0000-props-can-be-provided-with-setter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
- Start Date: 2020-05-15
- Target Major Version: 2.x, 3.x
- Reference Issues: N/A
- Implementation PR:

# Summary
- Make it simpler to pass `v-model` down in (say) wrapper components.

# Basic Example
```html
<template>
<label>
{{label}}
<input v-model="value" />
</label>
</template>
<script>
export default {
model: {
prop: 'value',
event: 'input'
},
props: {
label: String,
value: {
type: String,
set(value) {
this.$emit('input', value);
}
}
}
};
</script>
```

# Motivation
It is often required that we rewrite existing form components that accept `v-model`s in wrapper components. However, we cannot simply pass the `v-model` down from the wrapper to the wrapped component:

```html
<template>
<label>
{{label}}
<!--
What about putting a v-model here?
-->
<input
:value="value"
@input="$emit('input', $event.target.value)"
/>
</label>
</template>
<script>
export default {
model: {
prop: 'value',
event: 'input'
},
props: {
label: String,
value: String
}
};
</script>
```

# Detailed design
An error can be thrown when trying to set a prop without setter. However when a prop has a setter (in the `set` property, the same way as in `computed`), an attempt to set the prop will call the prop’s setter.

# Drawbacks
It may make Vue’s one-way data flow less apparent.

# Alternatives
https://github.com/vuejs/rfcs/pull/10:

```html
<template>
<label>
{{label}}
<input v-model="value" />
</label>
</template>
<script>
export default {
model: {
prop: 'value',
event: 'input'
},
props: {
label: String,
value: {
type: String,
as: 'valueProp'
}
},
computed: {
value: {
get() {
return this.valueProp;
},
set(value) {
this.$emit('input', value);
}
}
}
};
</script>
```

https://github.com/vuejs/rfcs/pull/140

# Adoption Strategy
N/A