【问题标题】:dynamically change select options in vue.js changes the display value在 vue.js 中动态更改选择选项会更改显示值
【发布时间】:2017-04-29 22:36:34
【问题描述】:

我为select 创建了一个自定义组件,它以 15 分钟的间隔显示一天的所有时间。我还可以传递一个可选的最小开始时间值。在我的 html 中,我使用了其中两个组件。 我已将组件定义为

Vue.component('time-select', {
   template: `
    <select :value="value" 
      ref= 'input'
      v-on:input="onChange($event.target.value)">
        <option value=""> {{firstOption}} </option>
        <option v-for="t in getHours()" :value="t">
          {{ t }}
        </option>
    </select>
 `,
 props: {
    value: String,
    startTime: String,
    firstOption: {
      type: String,
      default: "Select"
    },
    step: {
      type: Number,
      default: 15
    }
 },
 methods: {
   getHours: function() {    
      var startHr = 0;
      var startMin = 0;
      if (this.startTime) {
         var timeParts = this.startTime.split(/[\s:]+/);
         startHr = parseInt(timeParts[0]);
         startMin = parseInt(timeParts[1]);    
         var ampm = timeParts[2];
         if(ampm == "PM" && startHr < 12)
           startHr = startHr + 12;
         else if(ampm == "AM" && startHr === 12)
           startHr = startHr - 12;
     }      

     var hours = [];
     var start = new Date(1,1,1,startHr,startMin);  
     var end = new Date(1,1,2,0,0);
     if(this.startTime)
     {
        start.setMinutes(start.getMinutes() + this.step);
     }
     for (var d = start; d < end; d.setMinutes(d.getMinutes() + this.step)) 
     {          
        hours.push(this.format(d));
     }

      return hours;
   },
   format: function(date)
   {
      var hours = date.getHours();
      var minutes = date.getMinutes();
      var ampm = hours < 12? "AM" : (hours=hours%12,"PM");
      hours =  hours == 0? 12 : hours < 10? ("0" + hours) : hours;
      minutes = minutes < 10 ? ("0" + minutes) : minutes;
      var ret = hours + ":" + minutes + " " + ampm;
      return ret;
   },
   onChange: function(val) {
      this.$emit('input', val);
   },
}
});

JsFiddle 链接是https://jsfiddle.net/xsnswxu1/1/

现在,如果您从第一个下拉列表中选择任何值(例如上午 01:30),从第二个下拉列表中选择任何值(例如上午 03:30),然后再次将第一个下拉列表的值更改为 12:30 am,第二个下拉列表的值会自动更改(对于本示例,它是凌晨 02:30)。虚拟机数据保持不变。当我更改第一个下拉列表时,不应更改第二个下拉列表值。知道我做错了什么。 VM 没有更新,这很好,但是如果我更改第一个下拉列表,第二个下拉列表显示值会发生变化。

【问题讨论】:

  • 如果第一次开始时间发生变化,那么结束时间如何有效,因为第二次的值是基于开始时间的?如果有的话,更改开始时间应该清除结束时间。
  • 只要结束时间有效,就应该保持不变。虚拟机数据保持不变。不知道为什么vue会更新html值。我错过了什么还是 Vue 的问题。

标签: vuejs2 vue-component


【解决方案1】:

每当您使用 v-for 进行迭代时,您都应该添加一个 key 属性。

当 Vue 更新使用 v-for 渲染的元素列表时,它通过 默认使用“就地补丁”策略。如果数据的顺序 items 已更改,而不是移动 DOM 元素以匹配 项目的顺序,Vue 将简单地修补每个元素并 确保它反映了应该在该特定位置呈现的内容 索引。

如果您将模板更改为以下内容,它应该会按照您期望的方式工作。

<select :value="value" 
  ref= 'input'
  v-on:input="onChange($event.target.value)">
  <option value=""> {{firstOption}} </option>
  <option v-for="t in getHours()" :value="t" :key="t">
    {{ t }}
  </option>
</select>

更新fiddle

但是,代码仍然存在错误。如果您选择一个开始日期和结束日期,然后选择一个使结束日期无效的开始日期(因为现在开始在结束日期之后开始),那么你的 Vue(你在调用vm) 将包含无效的结束日期,即使结束日期选择列表看起来像是已清除选定的结束日期。这就是为什么我在上面建议在开始日期更改时清除结束日期。如果不这样做,那么您需要在开始日期更改时检查结束日期的有效性。

【讨论】:

  • 非常感谢。现在可以了。是的,当它变得无效时,我会清除结束日期。
  • 我添加了一个方法来清除无效的结束时间。 Fiddle Link
  • 我发现每次更改下拉值时都会执行 getHours() 方法。有没有更好的办法?
猜你喜欢
  • 2021-08-24
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 2011-10-08
  • 1970-01-01
  • 2021-12-24
  • 2018-01-29
相关资源
最近更新 更多