Vuejs2 动态更改vue.js中的选择选项会更改显示值

Vuejs2 动态更改vue.js中的选择选项会更改显示值,vuejs2,vue-component,Vuejs2,Vue Component,我为select创建了一个自定义组件,它以15分钟的间隔显示一天中的所有时间。我还可以传递可选的最小开始时间值。在我的html中,我使用了其中两个组件。 我已经将组件定义为 Vue.component('time-select', { template: ` <select :value="value" ref= 'input' v-on:input="onChange($event.target.value)"> <op

我为
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);
   },
}
});
Vue.component('time-select'{
模板:`
{{firstOption}}
{{t}
`,
道具:{
值:字符串,
开始时间:字符串,
第一种选择:{
类型:字符串,
默认值:“选择”
},
步骤:{
类型:数字,
默认值:15
}
},
方法:{
getHours:函数(){
var startHr=0;
var startMin=0;
如果(此.startTime){
var timeParts=this.startTime.split(/[\s:]+/);
startHr=parseInt(时间部分[0]);
startMin=parseInt(timeParts[1]);
var ampm=时间部件[2];
如果(ampm==“PM”&&startHr<12)
startHr=startHr+12;
else if(ampm==“AM”&&startHr==12)
startHr=startHr-12;
}      
var小时数=[];
var start=新日期(1,1,1,startHr,startMin);
var结束=新日期(1,1,2,0,0);
如果(此.startTime)
{
start.setMinutes(start.getMinutes()+此.step);
}
for(var d=start;d
JSIDLE链接是


现在,如果您从第一个下拉列表中选择任何值(例如01:30 am),从第二个下拉列表中选择任何值(例如03:30 am),然后再次将第一个下拉列表的值更改为12:30 am,则第二个下拉列表的值会自动更改(例如,它是02:30 am)。尽管如此,虚拟机数据仍保持相同。当我更改第一个下拉列表时,第二个下拉列表值不应更改。知道我做错了什么吗。VM未更新,这很好,但如果我更改第一个下拉列表,则第二个下拉列表显示值正在更改

无论何时使用
v-for
进行迭代,都应该添加一个属性

当Vue更新使用v-for呈现的元素列表时,它会 默认使用“就地补丁”策略。如果数据的顺序 项已更改,而不是移动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>

{{firstOption}}
{{t}
更新


然而,代码仍然有一个bug。如果您选择了开始日期和结束日期,然后选择了使结束日期无效的开始日期(因为现在开始日期在结束日期之后开始),那么您的Vue(您所称的
vm
)将包含无效的结束日期,即使结束日期选择列表看起来像是已清除了所选的结束日期。这就是为什么我在上面建议在开始日期更改时清除结束日期。如果没有,则无论何时开始日期更改,都需要检查结束日期的有效性。

如果第一个开始时间更改,如果第二个时间的值基于开始时间,那么结束时间如何有效?如果更改开始时间,则应清除结束时间。只要结束时间有效,它应保持不变。虚拟机数据保持不变。我不知道为什么vue会更新html值。我是遗漏了什么还是Vue的问题。非常感谢。现在可以了。是的,当结束日期无效时,我会清除它。我添加了一个方法来清除无效时的结束时间。我发现每次更改下拉列表值时都会执行getHours()方法。有没有更好的办法?