Skip to content
Advertisement

Why Vue Component Won’t Update On Select Change

I have a form that changes some text within a vue component when a select box is changed. I’ve created a highly minimized version of this in jsfiddle to show the issue I’m experiencing:

https://jsfiddle.net/ywaug7ft/

HTML:

<div id="app">
<h5>Select a gender</h5>
  <select v-model="gender">
    <option disabled="disabled" value>Select...</option>
    <option value="1">Male</option>
    <option value="2">Female</option>
    <option value="3">Couple</option>
  </select>
  <div></div>
  <detail-component v-for="(detail, index) in details" :data="detail" :index="index"></detail-component>

  {{details}}
</div>

<template id="details">
   <div>
     <h4><span v-if="item.gender == 3 && index == 0">Her</span><span
                v-else-if="item.gender == 3 && index == 1">His</span><span v-else>Your</span> Health Details</h4>
     <div>Index: {{index}}</div>
     <div>Gender: {{item.gender}}</div>
   </div>
</template>

Vue:

Vue.component('detail-component', {
  template: '#details',
  props: ['data', 'index'],
  data() {
    return {
      item: {
        gender: this.data.gender
      }
    }
  }
});

var app = new Vue({
  el: '#app',
  data: {
    gender: '',
    details: [],
    options: {
        gender: {
        "1": "Single Female",
        "2": "Single Male",
        "3": "Couple"
      }
    }
  },
  watch: {
    gender: function(val) {
      this.details = [];
      if (val == 1) {
        this.details.push({gender: 1});
      } else if (val == 2) {
        this.details.push({gender: 2});
      } else if (val == 3) {
        this.details.push({gender: 3}, {gender: 3});
      }
    }
  }
});

Basically, when I select female or male from the dropdown, my vue component should update the h tag to say Your Details. When I select couple, my view component should update to say Her Details and His Details. However, it’s not updating the first index to Her but instead maintains Your.

Take a look at the jsfiddle and you’ll see what I mean exactly.

Just trying to understand what I’m doing wrong. I thought that using watcher would be reactive in the component.

Advertisement

Answer

You are not watching inside the child if a prop value is getting updated.
So here whenever the prop data changes you need to watch it as well in the child component.

Watch Fiddle,

watch:{
  data(val){
    this.item.gender=val.gender
  }
}

Or computed property Fiddle.

computed:{
  item(){
    return this.data;
  }
}
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement