2017-04-25 47 views
2

我有以下Vue HTML。我知道这可以用其他模块来完成,但我不想使用,除非需要。我有一个选择表格,客户填写的日期是select,用于每天的开始和结束时间。显然这可能会变得多余,因为我将列出所有的时间(每15分钟在我的情况下)为option s每天2次和所有日子7次。它结束了几百行代码...一小时select ...有没有更好的方法来保持这种干爽?我宁愿把它留在Vue的土地上。或者JS的方法等等Keep VueJS snippet DRY

<div class="col-xs-4"> 
    <select class="form-control" v-model="newPost.hours.sunday.opens"> 
    <option value="" selected>Opens:</option> 
    <option value="12:00am">12:00am</option> 
    <option value="12:15am">12:15am</option> 
    <option value="12:30am">12:30am</option> 
    <option value="12:45am">12:45am</option 

...etc...etc x7 

回答

6

添加的属性与所有的时间到你的组件:

data() { 
    return { 
    times: ['12:00am', '12:15am', ...], 
    } 
} 

然后在模板中使用v-for生成选项:

<select class="form-control" v-model="newPost.hours.sunday.opens"> 
    <option value="" selected>Opens:</option> 
    <option v-for="time in times" :value="time">{{ time }}</option> 
</select> 
0

将它作为数据属性传递是可能的,但我认为根据您传递到时间选取器组件的开始时间来计算时间范围会更好。您可以使用moment.js轻松创建15分钟的时间。组件内部的步骤。所以不需要手动创建。

然后,您还可以修改关闭下拉菜单,使其仅显示开始时间之后的时间。动态更新。

并创建两个时间选取器组件循环的天['Monday', 'Tuesday', ...]v-for阵列。

在应用程序组件中,我已经动态地创建了空的数据模型,因此您每天都准备好对象。

请看下面的演示或此fiddle

moment.locale('en'); 
 

 
const timePickerComponent = { 
 
\t props: { 
 
    \t day: String, 
 
    caption: String, 
 
    options: Object 
 
    }, 
 
    template: ` 
 
    \t <div> 
 
    \t <select class="form-control" v-model="timeSelected" @change="timeChanged"> 
 
     <option value="">{{caption}}</option> 
 
     <option v-for="time in times">{{ time }}</option> 
 
     </select> 
 
    </div> 
 
    `, 
 
    data() { 
 
    \t return { 
 
    \t times: this.createTimes(), 
 
     timeSelected: '' 
 
    } 
 
    }, 
 
    watch: { 
 
    \t 'options.start'() { 
 
    \t this.times = this.createTimes(); // re-create times 
 
    } 
 
    }, 
 
    methods: { 
 
    \t timeChanged() { 
 
    \t console.log('changed', this.timeSelected) 
 
    \t this.$emit('changed', {day: this.day, selected: this.timeSelected}); 
 
    }, 
 
    \t createTimes() { 
 
    \t // 0:00am to 0:00pm 
 
     const formatStr = 'hh:mm a'; 
 
     let start = moment(this.options.start, formatStr); 
 
     let range = this.options.hours; // 8 hours 
 
     
 
     let times = new Array(range*4+1).fill(start); 
 
     console.log(start, times); 
 
    \t return times.map((item, index) => { 
 
     \t return (index > 0 ? item.add(15, 'm') : item).format(formatStr); 
 
     }); 
 
    } 
 
    } 
 
}; 
 

 
new Vue({ 
 
\t el: '#app', 
 
    data() { 
 
    \t return { 
 
    \t days: [ 
 
     'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' 
 
     ], 
 
    \t openOptions: { 
 
     \t start: "12:00 am", 
 
     hours: 24 
 
     }, 
 
     closeOptions: { 
 
     \t start: "12:00 am", 
 
     hours: 8 
 
     }, 
 
     newPost: undefined 
 
    } 
 
    }, 
 
    created() { 
 
    \t this.newPost = this.createEmptyPost(); 
 
    }, 
 
    methods: { 
 
    \t createEmptyPost() { 
 
    \t let newPost = {}; 
 
     this.days.forEach((day) => { 
 
     newPost[day] = { 
 
     \t openingTime: undefined, 
 
      closingTime: undefined 
 
     }; 
 
     }); 
 
     return newPost; 
 
    }, 
 
    \t closingChanged(val) { 
 
    \t this.newPost[val.day].closingTime = val.selected; 
 
    }, 
 
    \t openingChanged(val) { 
 
    \t console.log(val); 
 
    \t this.newPost[val.day].openingTime = val.selected; 
 
     console.log(moment(val.selected, 'hh:mm a').hour()); 
 
     this.closeOptions.start = moment(val.selected, 'hh:mm a'); 
 
    } 
 
    }, 
 
    components: { 
 
    \t timePicker: timePickerComponent 
 
    } 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script> 
 
<div id="app"> 
 
    <div v-for="day in days"> 
 
    {{day}}: 
 
    <time-picker :day="day" caption="Opens" :options="openOptions" @changed="openingChanged"></time-picker> 
 
    <time-picker :day="day" caption="Closes" :options="closeOptions" @changed="closingChanged"></time-picker> 
 
    <hr/> 
 
    </div> 
 
    
 
    <pre> 
 
{{newPost}} 
 
    </pre> 
 
</div>