动态更改 select 中的选项 vue.js 更改显示值
dynamically change select options in vue.js changes the display value
我为 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 link 是 https://jsfiddle.net/xsnswxu1/1/
现在,如果您 select 第一个下拉列表中的任何值(例如 01:30 am)和第二个下拉列表中的任何值(例如 03:30 am),然后再次将第一个下拉列表的值更改为 12:30 am,第二个下拉列表的值会自动更改(对于本例,它是 02:30 am)。 VM 数据保持不变。当我更改第一个下拉菜单时,不应更改第二个下拉菜单的值。知道我做错了什么。 VM 未更新,这很好,但如果我更改第一个下拉菜单,第二个下拉菜单显示值会发生变化。
每当您使用 v-for
进行迭代时,您应该添加一个 key 属性。
When Vue is updating a list of elements rendered with v-for, it by
default uses an “in-place patch” strategy. If the order of the data
items has changed, instead of moving the DOM elements to match the
order of the items, Vue will simply patch each element in-place and
make sure it reflects what should be rendered at that particular
index.
如果您将模板更改为以下内容,它应该会按您期望的方式工作。
<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(您're calling vm
) 将包含无效的结束日期,即使结束日期 select 列表看起来像 selected 结束日期已被清除。这就是为什么我在上面建议在开始日期更改时清除结束日期的原因。如果您不这样做,那么您将需要在开始日期更改时检查结束日期的有效性。
我为 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 link 是 https://jsfiddle.net/xsnswxu1/1/
现在,如果您 select 第一个下拉列表中的任何值(例如 01:30 am)和第二个下拉列表中的任何值(例如 03:30 am),然后再次将第一个下拉列表的值更改为 12:30 am,第二个下拉列表的值会自动更改(对于本例,它是 02:30 am)。 VM 数据保持不变。当我更改第一个下拉菜单时,不应更改第二个下拉菜单的值。知道我做错了什么。 VM 未更新,这很好,但如果我更改第一个下拉菜单,第二个下拉菜单显示值会发生变化。
每当您使用 v-for
进行迭代时,您应该添加一个 key 属性。
When Vue is updating a list of elements rendered with v-for, it by default uses an “in-place patch” strategy. If the order of the data items has changed, instead of moving the DOM elements to match the order of the items, Vue will simply patch each element in-place and make sure it reflects what should be rendered at that particular index.
如果您将模板更改为以下内容,它应该会按您期望的方式工作。
<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(您're calling vm
) 将包含无效的结束日期,即使结束日期 select 列表看起来像 selected 结束日期已被清除。这就是为什么我在上面建议在开始日期更改时清除结束日期的原因。如果您不这样做,那么您将需要在开始日期更改时检查结束日期的有效性。