nickmessing / babel-plugin-jsx-v-model

JSX Syntactic Sugar Plugin for v-model
MIT License
155 stars 12 forks source link

not working with custom inputs #6

Open rhyek opened 7 years ago

rhyek commented 7 years ago

The plugin is expecting there to always be a DOM event object passed to the event callback. With custom inputs, the parameter given is the actual new value.

See https://vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events.

nickmessing commented 7 years ago

@rhyek, are you sure? If JSX element is not a standard html/svg tag it's parsed as "component" and code looks like this.model = $$v, you can see it here

rhyek commented 7 years ago

I am pretty sure I was getting "Cannot read property 'value' of undefined" on a custom component that emitted a new value with the input event, so I assumed this was the issue.

nickmessing commented 7 years ago

If you'll ever meet this problem again can you please copy the code too?

On 25 Aug. 2017 10:53 am, "Carlos Gonzales" notifications@github.com wrote:

I am pretty sure I was getting "Cannot read property 'value' of undefined" on a custom component that emitted a new value with the input event, so I assumed this was the issue.

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/nickmessing/babel-plugin-jsx-v-model/issues/6#issuecomment-324779031, or mute the thread https://github.com/notifications/unsubscribe-auth/ABjuIqRp9hkfSX61qPFiOK_teThFJ9HHks5sbf8DgaJpZM4O7ES8 .

rhyek commented 7 years ago

Ok, I tested right now and am not getting the error anymore (something probably changed after I updated your module), but the value isn't being changed either.

This does not change the value:

<filter-input v-model={this.filtro}/>

This does:

<filter-input value={this.filtro} onInput={value => this.filtro = value}/>

In your example I see:

onChange={$$v => {
  _this.b = $$v;
}}

Maybe that's it? Shouldn't the default there be to use onInput unless I specify something else vía model (https://vuejs.org/v2/guide/components.html#Customizing-Component-v-model)?

nickmessing commented 7 years ago

@rhyek, yep, you are right, will fix it now

rhyek commented 7 years ago

@nickmessing, I just tested 2.0.2 and I'm sorry to say it's still not updating the value. Is there anything I can do to help you debug this?

nickmessing commented 7 years ago

@rhyek, it can be that it compiles to domPropsValue instead of value

nickmessing commented 7 years ago

Can you please check if this one works with your custom input?

    <something-else
      value={this.b}
      onInput={$$v => {
        this.b = $$v;
      }}
      {...{
        directives: [{
          name: "model",
          value: this.b
        }]
      }} />
rhyek commented 7 years ago

This works:

                    <filter-input
                      value={this.filtro}
                      onInput={$$v => this.filtro = $$v}
                      {...{
                        directives: [{
                          name: 'model',
                          value: this.filtro
                        }]
                      }}
                    />

But so does this:

                    <filter-input
                      value={this.filtro}
                      onInput={$$v => this.filtro = $$v}
                    />
nickmessing commented 7 years ago

@rhyek, well directives is required in some scenarios so we have to use it, I'll push a fix right now

rhyek commented 7 years ago

2.0.3 Still not working. Do you have a way to test this yourself? It might be that I'm doing something I'm not supposed to.

nickmessing commented 7 years ago

@rhyek, can you share code of your custom component?

rhyek commented 7 years ago
<template>
  <div class="filter-input input-group">
    <input
      ref="input"
      type="text"
      class="form-control"
      :value="value"
      :placeholder="placeholder || 'Filtrar...'"
      @input="input($event.target.value)"
      @keydown.stop.prevent.esc="clear"/>
    <span class="input-group-btn">
      <button v-if="withSearchButton" class="btn btn-default" type="button" tabindex="-1" @click="$emit('search')">
        <i class="fa fa-search"></i>
      </button>
      <button class="btn btn-default" type="button" tabindex="-1" @click="clear">
        <i class="fa fa-times text-danger"></i>
      </button>
    </span>
  </div>
</template>

<script>
import _ from 'lodash'

export default {
  props: {
    value: {
      type: String,
      default: null
    },
    placeholder: {
      type: String,
      default: null
    },
    delay: {
      type: Number,
      default: 300
    },
    withSearchButton: {
      type: Boolean,
      default: false
    }
  },
  created () {
    this.input = _.debounce(this.input, this.delay)
  },
  methods: {
    input (value) {
      this.$emit('input', value)
    },
    clear () {
      this.input.flush()
      this.$nextTick(() => {
        this.input(null)
        this.input.flush()
        this.$refs.input.focus()
      })
    }
  }
}
</script>
rhyek commented 7 years ago

Reformatted.

DM2489 commented 6 years ago

For what it's worth, this doesn't work with the Bootstrap-Vue custom checkboxes:

<b-form-checkbox v-model={this.consentForm.consent}/>

This does:

<b-form-checkbox v-bind={this.consentForm.consent} on-change={(value) => this.consentForm.consent = value} />

Here's their component:

https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/components/form-checkbox/form-checkbox.js

It doesn't appear to actually bind to the value.