How to bind components with vue js?

I have form and select components. In fact things are simple: I need two binding model.

The parent component:

    Vue.component('some-form', {
      template: '#some-form',
      data: function() {
        return {
          countryNameParent: ''
        }
      }
   });

The child component with items:

Vue.component('countries', {
  template: '#countries',
  data: function () {
    return {
      items: {
        "0": {
          "id": 3,
          "name": "Afghanistan"          
        },
        "1": {
          "id": 4,
          "name": "Afghanistan2"          
        },
        "2": {
          "id": 5,
          "name": "Afghanistan3"          
        }
      },
      countryName: ''
    }
  },
  props: ['countryNameParent'],
  created: function() {
    var that = this;
    this.countryName = this.countryNameParent;
  },

  methods: {
    onChange: function (e) {
      this.countryNameParent = this.countryName;
    }
  }
});

I'm using v-model to incorporate components above. Templates like this:

<template id="some-form">
  {{ countryNameParent }}
  <countries v-model="countryNameParent"></countries>
</template>

<template id="countries">
  <label for="">
    <select name="name" @change="onChange" v-model="countryName" id="">
      <option value="0">Select the country!</option>
      <option v-for="item in items" v-bind:value="item.name">{{ item.name }}</option>
    </select>
  </label>
</template>

My target is getting data in parent component to send it to server (real form is much bigger), however I can't get the value of the countryName in countryNameParent. Moreover, Parent should setting data in successor if not empty.

Here you go link where I've been attempting to do it several ways (see commented part of it). I know that I need to use $emit to set data correctly, I've even implemented model where I get image as base64 to send it by dint of the same form, hence I think solution is approaching!

Also: reference where I've built sample with image.

Answers:

Answer

Here is your countries component updated to support v-model.

Vue.component('countries', {
  template: `
  <label for="">
    <select v-model="countryName">
      <option value="0">Select the country!</option>
      <option v-for="item in items" v-bind:value="item.name">{{ item.name }}</option>
    </select>
  </label>
  `,
  data: function () {
    return {
      items: {
        "0": {
          "id": 3,
          "name": "Afghanistan"          
        },
        "1": {
          "id": 4,
          "name": "Afghanistan2"          
        },
        "2": {
          "id": 5,
          "name": "Afghanistan3"          
        }
      },
    }
  },
  props: ['value'],
  computed:{
    countryName: {
      get() { return this.value },
      set(v) { this.$emit("input", v) }
    }
  },
});

v-model is just sugar for setting a value property and listening to the input event. So to support it in any component, the component needs to accept a value property, and emit an input event. Which property and event are used is configurable (documented here).

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.