【问题标题】:Why Vue Component Won't Update On Select Change为什么 Vue 组件不会在选择更改时更新
【发布时间】:2019-01-30 05:08:59
【问题描述】:

我有一个表单,它在更改选择框时更改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});
      }
    }
  }
});

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

看看 jsfiddle 你就会明白我的意思了。

只是想了解我做错了什么。我认为在组件中使用 watcher 会是响应式的。

【问题讨论】:

    标签: javascript vue.js vuejs2 vue-component


    【解决方案1】:

    如果道具值正在更新,您不会在孩子内部观察。
    因此,每当道具data 更改时,您也需要在子组件中将其更改为watch。

    观看Fiddle,

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

    或计算属性Fiddle。

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

    【讨论】:

    • 我通常喜欢使用计算属性而不是观看,我认为它更干净。这样您就不必同时定义计算逻辑和存储结果的神奇位置。
    【解决方案2】:

    您使用了错误的参考:您的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,因此得到的是“Your”而不是“Her”。

    【讨论】:

      【解决方案3】:

      问题是由你的这部分代码引起的:

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

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

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

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

      【讨论】:

        【解决方案4】:

        就我而言,模板中有:v-model。但是v-model 不带冒号。这破坏了一切。

        【讨论】:

          猜你喜欢
          • 2020-01-19
          • 2021-11-11
          • 1970-01-01
          • 2021-06-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-17
          相关资源
          最近更新 更多