EricTalv
EricTalv

Reputation: 1049

sending drop-down value to parent

I have this form on my parent:

<template>
  <b-form @submit="onSubmit">
    <CountryDropdown/>
  </b-form>
</template>

<script>
import ...

export default {
  form: {
    country: ''
  }
}
</script>

This is my Dropdown component using vue-select:

<template>
  <v-select label="countryName" :options="countries" />
</template>

<script>
export default {
  data() {
    return {
      countries: [
        { countryCode: 'EE', countryName: 'Estonia' },
        { countryCode: 'RU', countryName: 'Russia' }
      ]
    }
  }
}
</script>

I need to pass the countryCode value to its parent's form.country. I tried using $emit, but I cant seem to figure out how upon selection it will set the parent value, and not upon submit.

EDIT:

The submitted solutions work great, I'll add my solution here:

I added an input event to my v-select:

<v-select @input="setSelected"  ... />

in my script i define the selected and setSelected method :

data() 
  return 
    selected: ''

setSelected(value) {
 this.selected = value.countryCode
 this.$emit("selected", value.countryCode)
}

And in the parent:

 <CountryDropdown v-on:selected="getCountry />

and parent script:

 getCountry(country) {
   this.form.country = country
 }

Upvotes: 1

Views: 1179

Answers (2)

tony19
tony19

Reputation: 138536

You could use Vue's v-model mechanism to bind the output of vue-select to form.country in the container.

In CountryDropdown, implement v-model:

  1. Add a prop named value 1️⃣, and bind it to vue-select.value 2️⃣
  2. Emit input-event with the desired value. In this case, we want to emit countryCode as the value. 3️⃣
<template>
  <v-select
    :value="value" 2️⃣
    @input="$emit('input', $event ? $event.countryCode : '')" 3️⃣
  />
</template>

<script>
export default {
  props: ['value'], // 1️⃣
}
</script>

Now, the container of CountryDropdown could bind form.country to it, updating form.country to the selected country's countryCode upon selection:

<CountryDropdown v-model="form.country" />

demo

Upvotes: 2

Andrew1325
Andrew1325

Reputation: 3579

As you seem to know, $emit is what you need to use to send an event from a component to its' parent. To make that happen you need to add a few more things to your current code.

To get the options to list in your v-select you should use a computed function to isolate the names, like this:

computed: {
    countryNames() {
      return this.countries.map(c => c.countryName)
    }
  },

You will then need to list the names in your v-select like this:

<v-select label="countryName" :items="countryNames" @change="selectedCountry" />

You will see that @change is calling a method, this will be the method to emit your country code and it can do so like this:

methods: {
    selectedCountry(e) {
      let code = this.countries.find(cntry => cntry.countryName === e)
      this.$emit('code', code.countryCode)
    }
  },

You will need a listener in your parent to hear the emit, so add something like this:

<CountryDropdown v-on:code="countryCodeFunction"/>

And then you just need a countryCodeFunction() in your methods that does something with the emitted code.

Upvotes: 0

Related Questions