Comments (16)
Should we consider renaming the input
event to update:value
when no argument is provided? It would be another breaking change
from core.
@posva I like that idea a lot! 🙂 It'd make component events more consistent and would actually solve a problem we currently have with transparent wrapper components. I just created a new issue to explore this further.
from core.
May I have a question about v-model
and .sync
here? 😅
IMO, both .sync
and v-model
are a little limited when use case becomes complicated. Because it often require you to do some validation or conversion during the two ways.
When the value is a primitive type, that's OK. But when it's an array like multiple checkbox or select in https://vuejs.org/v2/guide/forms.html , the data change is actually happened immediately without chance to validate, though you would receive an update event next. It looks like the same way to the primitive value but works different.
So I'd like to make sure in v3.0 whether the value pass to the v-model
or .sync
is immutable? immutable by default? optional immutable? or still mutable (I see the immutable/reactive observer in source code).
Thanks.
from core.
This is where we decided to bring .sync
back for 2.x and the original feature request was v-model
for multiple values.
Here are some potential problems I can think of:
With the current syntax being v-model="val"
, the actual prop in the binding is encapsulated, especially for native input elements like select
which we have quite a lot special logic. If we support provide directive arguments like v-model:title
, we have two choices for the default binding:
- Always enforce the argument, like
v-model:value
. While most of the components don't provide multiple two-way bindings this seems a little too verbose to me. - Keep
v-model
for the old magic and only provide arguments for non-value
bindings. This will make our syntax inconsistent:v-bind:title
stands for binding single prop whilev-bind
stands for binding all passed props. So isv-on
. If we have bothv-model
andv-model:title
it'll seem confusing with the experience of other directives.
from core.
Keep
v-model
for the old magic and only provide arguments for non-value bindings. This will make our syntax inconsistent:v-bind:title
stands for binding single prop whilev-bind
stands for binding all passed props. So isv-on
. If we have bothv-model
andv-model:title
it'll seem confusing with the experience of other directives.
@Justineo That's a fair point. I think everywhere else that we have a directive with an optional argument, the lack of arguments is used to spread an object. Though I don't think this will actually cause much confusion in practice, since v-model
is introduced so early and is used so frequently. It's also different from v-bind
and v-on
in that its primary use case is argument-less (and the version with an argument is only introduced later in the guide), whereas v-bind
and v-on
are the opposite.
So I'm still in favor of option 2. What do you think?
from core.
So I'm still in favor of option 2. What do you think?
Not quite sure about it…it also disables usage like v-bind.sync="obj"
.
from core.
Good point. Though the use case is relatively rare, I agree we should handle it. Maybe a modifier like v-model.spread="object"
could address that use case. Thoughts?
from core.
Should we consider renaming the
input
event toupdate:value
when no argument is provided? It would be another breaking change
So how could we bind an event named update:value
in template without v-model
? Is <MyComponent @update:value="xxx" />
or <MyComponent v-on:update:value="xxx" />
(two colons?) a valid syntax?
from core.
I have another idea. Not quite sure it's good enough, but just an idea. 😅
class Foo extends Vue {
props,
data,
model() {
return {
value, ...others
}
},
...
}
In another word, because the update event must be defined in the component to make sense. So maybe it's good to define model/models internal, not external as a syntax sugar only.
When we return a member in model()
, it is not reactive but would emit an event when updated.
Thanks.
from core.
So how could we bind an event named update:value in template without v-model? Is <MyComponent @update:value="xxx" /> or (two colons?) a valid syntax?
I don't see why we couldn't make it valid, if it isn't already. 🙂 I don't think we currently allow for multiples arguments on a directive, do we?
In another word, because the update event must be defined in the component to make sense. So maybe it's good to define model/models internal, not external as a syntax sugar only.
When we return a member in model(), it is not reactive but would emit an event when updated.
I don't think I fully understand what you're suggesting. Would you mind providing a more complete example to demonstrate the use case?
from core.
I don't see why we couldn't make it valid if it isn't already. 🙂 I don't think we currently allow for multiples arguments on a directive, do we?
Update: Found that syntax like @update:value="xxx"
already supported well in v2. No more asked. 🙂
In v2 doc link, <input v-model="searchText">
does the same thing as <input v-bind:value="searchText" v-on:input="searchText = $event.target.value">
(similar to v-model
in custom components). So v-model
is just a sugar syntax imo which means you can choose both v-model
and v-bind
+v-on
ways to do that. If we include a colon in a event name. That means we must use v-model
and it's not a sugar syntax anymore.
For example, think about we have a custom component <InputDate />
which supports v-model
and would init the value to new Date()
if nothing passed in. For this, it's necessary to support only having an event handler but without value passer at the same time. It works in v2 as <InputDate @input="date = $event" />
. But I am not sure update:value
is a good event name for that in the future.
I don't think I fully understand what you're suggesting. Would you mind providing a more complete example to demonstrate the use case?
Well, I have realized that's not a good idea. But give an explanation here.
I have written many custom components which support v-model
like:
<template>
<input :value="localValue" @input="handle" />
</template>
<script>
export default {
props: ['value'],
data() {
return { localValue: this.value }
},
watch: {
value(val) { this.localValue = val }
},
methods: {
handle(event) {
let val = $event.target.value
// do some validations/transformations
this.setValue(val)
},
otherActions() {
// do sth.
this.setValue(...)
},
setValue(val) {
this.localValue = val
this.$emit('input', val)
}
}
}
</script>
So I have a thought to simplifiy that maybe like:
<template>
<input :value="localValue" @input="handle" />
</template>
<script>
export default {
// or `model: { value: { type: String, default: xxx }},`
// or `props: { value: { ..., model: true }}`
model: ['value'],
methods: {
handle(event) {
let val = $event.target.value
// do some validations/transformations
this.setValue(val)
},
otherActions() {
// do sth.
this.setValue(...)
},
}
}
</script>
It supplies a data named loaclXxx
and a method setXxx(v)
automatically. And when you call setXxx(v)
, an event named input
or update:xxx
would be emitted if v
is different with localXxx
.
and actually the code below also works the same:
<template>
<input :value="localValue" @input="handle" />
</template>
<script>
const mixinModel = {
data() {
return { localValue: this.value }
},
watch: {
value(val) { this.localValue = val }
},
methods: {
setValue(val) {
this.localValue = val
this.$emit('input', val)
}
}
}
export default {
mixins: [mixinModel],
props: ['value'],
methods: {
handle(event) {
let val = $event.target.value
// do some validations/transformations
this.setValue(val)
},
otherActions() {
// do sth.
this.setValue(...)
},
}
}
</script>
from core.
Just linking this comment here for reference (implementation details) #9 (comment)
from core.
@chrisvfritz I'm starting to prepare for moving things we are discussing here to public RFCs. Do you want to champion this one?
from core.
@yyx990803 Happy to. 🙂 Filling out the RFC now.
from core.
This is now a public RFC, so further discussion should happen there. @Justineo Your thoughts on the best compromise for spreading an object would be especially welcome. 🙂
from core.
Closing in favor of the public RFC.
from core.
Related Issues (20)
- Custom elements that use vue components within have slot elements removed HOT 1
- Two-way `<input v-model>` binding loses downstream sync in child component HOT 3
- v-model causes different behavior to :value="value" @input="value = $event.target.value"
- [@vue/compiler-sfc] Failed to resolve import source HOT 1
- The License comment in the first lines got lost with vue3 HOT 2
- The arrow function is used in vuex, causing computed to fail to get the state in response HOT 1
- Uncaught (in promise) Maximum recursive updates exceeded in component <RouterView> HOT 7
- Reactivity maybe be broken with nested computed and vue-router HOT 9
- Default value of defineModel is not handled as a local ref HOT 1
- Donating Funds to Vuejs/Core HOT 1
- Generic props extending boolean should apply Boolean casting HOT 1
- Why is the length of the slot 0? HOT 1
- App crashes when using router-view in a top-level route target when there's a transition in the top level RouterView's slot
- keep-alive组件里面的变量storageContainer存在内存泄漏 HOT 4
- The register mismatch between display value in input and reactive variable HOT 9
- [SSR] Hydration error using v-bind in scoepd styles HOT 2
- Nested calls to `runWithContext` resets the app for the rest of the top `runWithContext` call
- @vue/compiler-sfc 单独在vscode插件中使用时,无法正确打包 HOT 2
- [Bug][Vue SFC Playground] Playground has a memory leak problem HOT 1
- `<select>` with `v-model` didn't update DOM after mutating data HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from core.