0
votes

I have a vue component in the html and want to pass props to the js code and down to the vue component.

so in my html index.html

<div id="js-group-discounts">
  <div class="form-group required">
    <datepicker
      input-label="From">
    </datepicker>
  </div>
  <div class="form-group required">
    <datepicker
      input-label="To">
    </datepicker>
  </div>
</div>

Then in my js

  import Vue from "vue"
  import Datepicker from "../components/DatePicker"

  Vue.use(Datepicker)    
  new Vue({
   el: "#js-group-discounts",
   props: {
    inputLabel: {
     type: String,
  },
},
components: {
  Datepicker,
},
mount: {
  console.log(this.inputLabel) // returns undefinend
 },
})

This is the Datepicker child component

<template>
 <div >
    <label for="for">label</label>
    <input  type="text"
            class="form-control form-control-info"
            placeholder="dd/mm/yyyy"
            name="this.label"
            id="this.label"
            pattern="\d{1,2}/\d{1,2}/\d{4}"
            required
            v-model="isInput"
            v-on:keyup="updateCalendar($event)"
            ref="startdate"
            @blur="blur"
            @focus="focus">
    <datepicker format="dd/MM/yyyy"
                id="start_calendar"
                input-class="form-control"
                placeholder="dd/mm/yyyy"
                v-model="isPicker"
                :inline="true"
                v-show="isOpen"
                @mouseover.native="mouseOver"
                @selected="updateInput"></datepicker>
  </div>
</template>

<script>
 import Vue from "vue"
 import Datepicker from "vuejs-datepicker"
 Vue.use(Datepicker)

 export default {
    name: "datepicker",
    components: {
        Datepicker
    },

}

eventually i want to pass this down in the data to a child component but can't get passed this bit of passing the value from the html. Any help?

2
@divine they are setting the value in the js. I want to pass the value of the prop set in the html - Adam
all values should be stored in javascript objects. if you want to pass any values from parent to child you have to send the corresponding javascript object from parent to child. - divine
So you can’t add a component to the html and have server side code set properties to pass down? This seems like something it should do. I find it hard to believe that this can’t be done. - Adam
you goal is to pass data from parent component to child component, am i correct? - divine

2 Answers

1
votes

From your question, I figured that you want the consuming parent to have access to the inputLabel in the <datepicker> component. The parent usually does not have knowledge of the child's properties (remember that inputLabel is a property of the child component, not that of the parent).

In this case, you might want to use the following strategy:

  • Use vm.$emit to emit a custom event, say datepickermounted, when the datepicker component is mounted. The consuming parent can then listen to this event using v-on:datepickermounted and receive data from the child component
  • The vm.$emit can have a payload containing the unique ID of the component, and also the associated inputLabel of the component
  • The parent has an array, say datepickers, that stores these emitted data. The parent listens onto the custom event, and upon receiving it, pushes it to its own data. Now the parent has access too all the <datepicker> child components' inputLabel :)

var Datepicker = Vue.component('datepicker', {
  template: '#datepicker',
  props: {
    inputLabel: {
      type: String
    }
  },
  mounted() {
    // Let parent know that a new datepicker has been mounted
    this.$emit('datepickermounted', {
      id: this._uid,
      label: this.inputLabel
    });
  }
});

new Vue({
  el: "#js-group-discounts",
  data: {
    datepickers: []
  },
  components: {
    Datepicker
  },
  methods: {
    storeDatepickerLabel(payload) {
      this.datepickers.push(payload);
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="js-group-discounts">
  <div class="form-group required">
    <datepicker input-label="datepickerLabel1" v-on:datepickermounted="storeDatepickerLabel"></datepicker>
  </div>
  <div class="form-group required">
    <datepicker input-label="datepickerLabel2" v-on:datepickermounted="storeDatepickerLabel"></datepicker>
  </div>
  
  <hr />
  
  <ul>
    <li v-for="(dp, index) in datepickers" :key="index">
      <strong>Datepicker id</strong>: {{ dp.id }}<br />
      <strong>Datepicker label</strong>: {{ dp.label }}
    </li>
  </ul>
</div>

<script type="text/template" id="datepicker">
  <div class="dummy">
    I am a dummy datepicker component<br /> My label is {{this.inputLabel}}.
  </div>
</script>

Alternatively, you can use refs to access the component, but be warned that vm.$refs are not reactive (e.g. if the inputLabel gets updated, you will not see it change!).

var Datepicker = Vue.component('datepicker', {
  template: '#datepicker',
  props: {
    inputLabel: {
      type: String
    }
  }
});

new Vue({
  el: "#js-group-discounts",
  components: {
    Datepicker
  },
  mounted() {
    this.$nextTick(function() {
      console.log(this.$refs.datepicker1.inputLabel);
      console.log(this.$refs.datepicker2.inputLabel);
    });
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="js-group-discounts">
  <div class="form-group required">
    <datepicker input-label="datepickerLabel1" ref="datepicker1" ></datepicker>
  </div>
  <div class="form-group required">
    <datepicker input-label="datepickerLabel2" ref="datepicker2" ></datepicker>
  </div>
</div>

<script type="text/template" id="datepicker">
  <div class="dummy">
    I am a dummy datepicker component<br /> My label is {{this.inputLabel}}.
  </div>
</script>
-1
votes

var Datepicker = Vue.component('datepicker', {
  template: '#datepicker',
  props: {
    inputLabel: {
      type: String
    }
  }
});

new Vue({
  el: "#js-group-discounts",
  components: {
    Datepicker
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="js-group-discounts">
  <div class="form-group required">
    <datepicker input-label="datepickerLabel1"></datepicker>
  </div>
  <div class="form-group required">
    <datepicker input-label="datepickerLabel2"></datepicker>
  </div>
</div>

<script type="text/template" id="datepicker">
  <div class="dummy">
    I am a dummy datepicker component<br /> My label is {{this.inputLabel}}.
  </div>
</script>