为什么Vue组件无法在选择更改时更新

时间:2018-08-23 18:37:08

标签: javascript vue.js vuejs2 vue-component

我有一个表单,可以在更改选择框时更改vue组件中的某些文本。我在jsfiddle中创建了一个高度最小化的版本,以显示我遇到的问题:

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});
      }
    }
  }
});

基本上,当我从下拉列表中选择femalemale时,我的vue组件应将h标签更新为Your Details。当我选择couple时,我的视图组件应更新为说Her DetailsHis Details。但是,它不会将第一个索引更新为Her,而是维护Your

看看jsfiddle,您会明白我的意思。

只是想了解我在做什么错。我以为使用watcher会对组件产生反应。

3 个答案:

答案 0 :(得分:1)

如果prop值正在更新,您就不会在孩子里面观看。
因此,在这里,每当道具data发生变化时,您也需要在子组件中watch对其进行更改。

观看Fiddle

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

或计算属性Fiddle

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

答案 1 :(得分:1)

您使用了错误的引用:您的detail-component收到了data,但是模板中的引用item

如果您按以下方式更改模板:

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

它将起作用(请参阅此Fiddle)。

这里的问题是,您在第一个细节对象中以某种方式具有性别1,因此得到的是“您的”而不是“她的”。

答案 2 :(得分:0)

问题是由您的这段代码引起的:

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

当您将prop中的gender属性的值分配给data()对象内部的属性时,它将立即失去引用。因此,data道具更新后,并没有更新您的item.gender

如果您的目的只是为了将alias的性别转换为一个具有较短名称的变量以方便使用,则可以使用computed属性,该属性在每次更改data时也会更新

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