Vue: v-bind="$attrs" and problems with "value" attribute for multi-checkboxes

Created on 28 Mar 2018  路  8Comments  路  Source: vuejs/vue

Version

2.5.16

Reproduction link

https://codepen.io/anon/pen/aYqoYL?editors=1010

Steps to reproduce

  • Check the checkbox
  • See that the value is set to "null" even though the input element has its value (correctly) set to "foo"

What is expected?

  • The value passed through "$attrs" should be the checkbox's value used

(or, the value never hits the DOM element, the fact that it is present on the DOM element but isn't used in the model is a conflict IMO)

What is actually happening?

  • Null is set

Most helpful comment

I get your point, but I'm not sure if this is a bug or not. We need some feedback from the core team.

My solution is partly based on this example code, where value is bound explicit and used with disabled attribute inheritance. source

Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  computed: {
    inputListeners: function () {
      var vm = this
      // `Object.assign` merges objects together to form a new object
      return Object.assign({},
        // We add all the listeners from the parent
        this.$listeners,
        // Then we can add custom listeners or override the
        // behavior of some listeners.
        {
          // This ensures that the component works with v-model
          input: function (event) {
            vm.$emit('input', event.target.value)
          }
        }
      )
    }
  },
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on="inputListeners"
      >
    </label>
  `
})

All 8 comments

Check the modified codepen. I changed the component logic to match default native multi checkbox behavior.

https://codepen.io/anon/pen/NYQWzo?editors=1011

@emanuelmutschlechner I don't think your codepen is relevant here (though I appreciate you working toward a solution!). Adding an explicit value prop to my original pen and putting that prop on the input field works around the bug - as can be seen in this modified pen. The point is that that shouldn't need to be done.

v-bind=$attrs should be passing value to the input already in my original pen, and it isn't doing so in a way v-model is picking up on.

@pearofducks If you want v-model to pick up the value defined on your component, explicitly bind value in your custom component

https://codepen.io/anon/pen/GxVJzW?editors=1010

@emanuelmutschlechner - please read my previous response. With $attrs this shouldn't be necessary. I'm pretty confident this is a valid bug, but I appreciate you trying to help.

I get your point, but I'm not sure if this is a bug or not. We need some feedback from the core team.

My solution is partly based on this example code, where value is bound explicit and used with disabled attribute inheritance. source

Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  computed: {
    inputListeners: function () {
      var vm = this
      // `Object.assign` merges objects together to form a new object
      return Object.assign({},
        // We add all the listeners from the parent
        this.$listeners,
        // Then we can add custom listeners or override the
        // behavior of some listeners.
        {
          // This ensures that the component works with v-model
          input: function (event) {
            vm.$emit('input', event.target.value)
          }
        }
      )
    }
  },
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on="inputListeners"
      >
    </label>
  `
})

Maybe this issue is somewhat related to #6216?

I think both of you are right. And, @emanuelmutschlechner, you are correct, right now this is the way of doing it: @chrisvfritz explains the state of the art and future approaches here:

alt="Vue 3 presentation by Chris Fritz" />

(https://www.youtube.com/watch?v=b554XmaTWrw)

Just wanted to that i've also faced this in my project.
Basically the problem can be narrowed to this:

// this works with emit('input')
v-bind:value="value"

// this fails to work with emit('input')
v-bind="{ value:value }"

So yeah, we have to explicitly set the :value to make things work, as @emanuelmutschlechner said earlier.
Imho, this seems more like a bug.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

finico picture finico  路  3Comments

gkiely picture gkiely  路  3Comments

paceband picture paceband  路  3Comments

bdedardel picture bdedardel  路  3Comments

franciscolourenco picture franciscolourenco  路  3Comments