5
votes

How to emit the 'checked' value from a child to the parent in the right way?

My checkbox is a nested component that uses v-checkbox from Vuetify. I would like to emit the checked value to his parent. Now, I am doing that emitting $event and that works, because $emit contains the true/false value but I don't know why (I've thought that I need to emit $event.target.checked but this is undefined).

Checkbox.vue

<template>
  <v-checkbox color="primaryGreen" hide-details @change="$emit('change', $event)">
    <span slot="label" class="checkbox-label">
      <slot></slot>
    </span>
  </v-checkbox>
</template>

Form.vue (parent)

<v-layout id="different-address-checkbox">
  <v-flex>
   <checkbox @change="sth">
    <span>Different Address</span>
   </checkbox>
  </v-flex>
</v-layout>

export default {
  data() {
    return {
      differentAddress: false
    };
  },
  methods: {
    sth(value) {
      this.differentAddress = value;
    }
  }
};

I don't understand why $emit contains true/false instead of the whole event with event.target.checked and I am not sure what is the right way to emit the checked value from child to parent.

3
Bind the checkbox value to a data property of the checkbox component, then you can emit the value in a methodpaddyfields

3 Answers

6
votes

v-checkbox is not a native form element. It emits whatever the author of the Vuetify framework decided it would emit. In this case, a boolean.

You're correct that when working with form elements you usually need to access the value with $event.target.checked or $event.target.value, but this doesn't apply to custom components.

Here's the relevant part in Vuetify's source:

internalValue: {
    get () {
      return this.lazyValue
    },
    set (val) {
      this.lazyValue = val
      this.$emit(this.$_modelEvent, val)
    }
},

When the component's value changes, internalValue is pushed to the parent (your child component).

0
votes

Move

@change="$emit('change', $event)

to a method propety

0
votes

I had a very similar problem, complex data model and nested for-loops. I needed an easy way to get the v-checkbox which changed checked-change-state.

This is how I solved it:

<div v-for="unitLocation in groupedResources" v-bind:key="unitLocation.node.TelldusUnitLocation_Name">

    <v-checkbox
        @change="toggledLocation(unitLocation)"
        v-model="unitLocation.node.checked"
        :label="unitLocation.node.TelldusUnitLocation_Name"
        hide-details
    ></v-checkbox>

    <!-- more code here -->
</div>

(unitLocation is a nested object itself with node and children-properties, but that's not important for the solution)

And then in my code:

methods: { 
  toggledLocation(args) {
    debugger; /*see image below, console in chrome*/
  }
}

Output in Chrome (I printed out the args parameter in debug console in Chrome): Output in Chrome