Giter VIP home page Giter VIP logo

Comments (16)

posva avatar posva commented on May 3, 2024

Should we consider renaming the input event to update:value when no argument is provided? It would be another breaking change

from core.

chrisvfritz avatar chrisvfritz commented on May 3, 2024

@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.

Jinjiang avatar Jinjiang commented on May 3, 2024

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.

Justineo avatar Justineo commented on May 3, 2024

vuejs/vue#4946

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:

  1. 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.
  2. 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 while v-bind stands for binding all passed props. So is v-on. If we have both v-model and v-model:title it'll seem confusing with the experience of other directives.

from core.

chrisvfritz avatar chrisvfritz commented on May 3, 2024

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 while v-bind stands for binding all passed props. So is v-on. If we have both v-model and v-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.

Justineo avatar Justineo commented on May 3, 2024

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.

chrisvfritz avatar chrisvfritz commented on May 3, 2024

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.

Jinjiang avatar Jinjiang commented on May 3, 2024

Should we consider renaming the input event to update: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.

Jinjiang avatar Jinjiang commented on May 3, 2024

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.

chrisvfritz avatar chrisvfritz commented on May 3, 2024

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.

Jinjiang avatar Jinjiang commented on May 3, 2024

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.

yyx990803 avatar yyx990803 commented on May 3, 2024

Just linking this comment here for reference (implementation details) #9 (comment)

from core.

yyx990803 avatar yyx990803 commented on May 3, 2024

@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.

chrisvfritz avatar chrisvfritz commented on May 3, 2024

@yyx990803 Happy to. 🙂 Filling out the RFC now.

from core.

chrisvfritz avatar chrisvfritz commented on May 3, 2024

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.

yyx990803 avatar yyx990803 commented on May 3, 2024

Closing in favor of the public RFC.

from core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.