0
votes

Im trying to use a component which changes the years of experience with a programming language. ir order to do so i use a couple of buttons to add and subtract the years, and a 'tech' prop to pass the language. i.e: PHP, JS, etc.

<script type="text/template" id="years_template">
<div>
    <p>How mane years of experience with {{ tech }} do you have?</p>

    <p>
        Answer: <strong>{{ years }}</strong>

        <button type="button"
                class="btn"
                @click="add">+</button>

        <button type="button"
                :disabled="years == 0"
                class="btn"
                @click="sub">-</button>
    </p>
</div>
</script>

My global variables are years_php and years_JS, and im trying to reuse the component "years-exp" so each one changes each global variable. I manage to do one of them by following this tutorial. However, when i wanted to reuse the years-exp component with just one emit and listen event, it always modified years_php variable, so i had to use a 'test' prop and check its value for different cases, here is my years-exp component:

Vue.component('years-exp', {
    template: '#years_template',
    data(){
      return {
        years : 0
      }
    },
    watch:{
      'years': function(years, oldYears){
        console.log('years changed from %s to %s', oldYears, years)
        switch (this.test) {
          case "years_php":
            bus.$emit('PHPyears-changed', years);
          break;
          case "years_js":
            bus.$emit('JSyears-changed', years);
          break;
        }
      },
    },
    methods: {
        add: function () {
            this.years++;
        },
        sub: function () {
            this.years--;
        },
    },
    props: ['test','tech']
});

And add the following code to my Vue instance:

created: function () {
      // store this to use with Vue.set
      var temp = this;
      bus.$on('PHPyears-changed', function (years) {
        Vue.set(temp, 'years_php', years);
        //Vue.set(temp, 'years_js', years)
      });
      bus.$on('JSyears-changed', function (years) {
        Vue.set(temp, 'years_js', years);
        //Vue.set(temp, 'years_js', years)
      })
    },

And here i insert them in html:

    <years-exp test="years_php" tech="PHP"></years-exp>
    <years-exp test="years_js" tech="JS"></years-exp>

Is there another way to do this in Vue.JS 2+ ?

1

1 Answers

0
votes

VueJS 2 uses an event pattern to handle parent-child communication. So basically, in order to have communication between child and parent you don't necessarily need a bus. You can do the following:

//your re-usable component code
this.$emit('years-changed', years);


//your component that uses <years-exp> (parent of years-exp)
<years-exp test="years_php" tech="PHP" @years-changed="handleYearsChanged"></years-exp>

methods:{
  handleYearsChanged:function(yearsValueFromChild){  
   //here you receive exactly the value you sent via $emit in child
  }
}

In case you need to send the event to a component above the parent in hierarchy then you would have to use the bus but for parent-child communication you can use this pretty simple pattern.