最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why Vue Component Won't Update On Select Change - Stack Overflow

programmeradmin2浏览0评论

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

/

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-ponent v-for="(detail, index) in details" :data="detail" :index="index"></detail-ponent>

  {{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:

Vueponent('detail-ponent', {
  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 ponent should update the h tag to say Your Details. When I select couple, my view ponent 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 ponent.

I have a form that changes some text within a vue ponent 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/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-ponent v-for="(detail, index) in details" :data="detail" :index="index"></detail-ponent>

  {{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.ponent('detail-ponent', {
  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 ponent should update the h tag to say Your Details. When I select couple, my view ponent 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 ponent.

Share Improve this question edited Aug 23, 2018 at 18:41 Robert Harvey 181k48 gold badges348 silver badges513 bronze badges asked Aug 23, 2018 at 18:37 RobDiabloRobDiablo 2053 silver badges12 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 4

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 ponent.

Watch Fiddle,

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

Or puted property Fiddle.

puted:{
  item(){
    return this.data;
  }
}

You are using the wrong reference: your detail-ponent receives data but your reference item in your template.

If you change the template as follows:

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

it will work (see this Fiddle).

The problem here was that you somehow had gender 1 in the first detail object and therefore got "Your" instead of "Her".

In my case, I had :v-model in the template. But v-model does not take the colon. That broke everything.

The problem is caused by this part of your code:

  data() {
      return {
        item: {
          gender: this.data.gender
        }
      }
    }

When you assigned the value of the gender property from your prop into a property inside your data() object, it loses reference immediately. So when the data prop was updated, it didn't update your item.gender.

If your purpose is just to alias the gender into a variable with shorter name for ease of use, you can use puted properties which will also update every time the data is changed.

puted: {
    item() {
      return this.data
    }
}
发布评论

评论列表(0)

  1. 暂无评论