JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
	<div id="app">
		<h1 class="tit">Schedule</h1>
		<p class="auther">jayzou</p>
		<Schedule 
			:time-ground="['9:00', '18:00']"
			:week-ground="['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']" 
			:color="[
				'#2B2E4A',
				'#521262',
				'#903749',
				'#53354A',
				'#40514E',
				'#537780',
			]" 
			:task-detail="[

				[
					{
						dateStart: '09:30',
						dateEnd: '10:30',
						title: 'Metting',
						detail: 'Metting (German: Mettingen) is a commune in the Moselle department in Grand Est in north-eastern France.'
					},

					{
						dateStart: '11:30',
						dateEnd: '13:50',
						title: 'Metting',
						detail: 'Metting (German: Mettingen) is a commune in the Moselle department in Grand Est in north-eastern France.'
					},
					
				],
				[
					{
						dateStart: '10:30',
						dateEnd: '12:00',
						title: 'Metting',
					},
					{
						dateStart: '12:30',
						dateEnd: '14:50',
						title: 'Metting',
					}
					
				],
				[
					{
						dateStart: '12:30',
						dateEnd: '13:30',
						title: 'Metting',
					},
					{
						dateStart: '15:30',
						dateEnd: '16:50',
						title: 'Metting',
					}
					
				],
				[
					{
						dateStart: '09:50',
						dateEnd: '10:50',
						title: 'Metting',
					},
					{
						dateStart: '11:30',
						dateEnd: '13:50',
						title: 'Metting',
					}
					
				],
				[
					{
						dateStart: '12:30',
						dateEnd: '13:30',
						title: 'Metting',
					},
					{
						dateStart: '14:30',
						dateEnd: '15:50',
						title: 'Metting',
					}
					
				]
			]">
		</Schedule>
	</div>

CSS

/* http://meyerweb.com/eric/tools/css/reset/ 
		   v2.0 | 20110126
		   License: none (public domain)
		*/
		html, body, div, span, applet, object, iframe,
		h1, h2, h3, h4, h5, h6, p, blockquote, pre,
		a, abbr, acronym, address, big, cite, code,
		del, dfn, em, img, ins, kbd, q, s, samp,
		small, strike, strong, sub, sup, tt, var,
		b, u, i, center,
		dl, dt, dd, ol, ul, li,
		fieldset, form, label, legend,
		table, caption, tbody, tfoot, thead, tr, th, td,
		article, aside, canvas, details, embed, 
		figure, figcaption, footer, header, hgroup, 
		menu, nav, output, ruby, section, summary,
		time, mark, audio, video {
			margin: 0;
			padding: 0;
			border: 0;
			font-size: 100%;
			font: inherit;
			vertical-align: baseline;
		}
		/* HTML5 display-role reset for older browsers */
		article, aside, details, figcaption, figure, 
		footer, header, hgroup, menu, nav, section, main {
			display: block;
		}
		body {
			line-height: 1;
		}
		ol, ul {
			list-style: none;
		}
		blockquote, q {
			quotes: none;
		}
		blockquote:before, blockquote:after,
		q:before, q:after {
			content: '';
			content: none;
		}
		table {
			border-collapse: collapse;
			border-spacing: 0;
		}

		body {
		  font-size: 1.6rem;
		  font-family: "Helvetica Neue",Helvetica,Arial,"Hiragino Sans GB","Hiragino Sans GB W3","Microsoft YaHei UI","Microsoft YaHei","WenQuanYi Micro Hei",sans-serif;
		  color: #222222;
		  background-color: white;
		}
		.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}
	
		.tit{
			text-align: center;
			font-size: 4rem;
			margin-top: 4rem;
		}
		.auther{
			font-size: 2rem;
			text-align: center;
			margin-top: 1.5rem;
			margin-bottom: 4rem;
			color: #95a5a6;
		}
    
   ...

JavaScript

Vue.config.debug = true;
Vue.config.silent = false;
Vue.config.async = false;
Vue.config.devtools = true;

modal = Vue.component('Modal', {
		props: {
			show: {
				type: Boolean,
				default: false
			},
			showModalDetail: {
				type: Object,
				default(){}
			},
		},
    template:'\
    	<div class="modal-mask" v-show="show" transition="modal" v-on:click="close">\
	    <div class="modal-wrapper">\
	      <div class="modal-container" :style="{\'backgroundColor\': showModalDetail.styleObj.backgroundColor}">\
	        <div class="modal-header">\
	          <a class="close" @click="show = false">X</a>\
	        </div>\
	        <div class="modal-body">\
	        	<h2>{{showModalDetail.title}}</h2>\
	        	<small>{{showModalDetail.week}}  {{showModalDetail.dateStart}} - {{showModalDetail.dateEnd}}</small>\
	        	<p>{{showModalDetail.detail}}</p>\
	        </div>\
	      </div>\
	    </div>\
	</div>\
    ', 
		methods: {
			close(e) {
				if(e.target.className == "modal-wrapper") this.show = false;
				// console.log(e);
				// console.log(e.target.className)
			}
		}
})

schedule = Vue.component('Schedule', {
	props: {
		timeGround: {
      coerce: function (val) {
      	 console.log('Enter in coerce : ' + value);
				if(value && value.length == 2){
					let startTime = value[0].split(":")[0] * 1;
					let endTime = value[1].split(":")[0] * 1;
					value = [];
					for(let i = startTime; i <= endTime; i++){
						 console.log(i);
						// value.push()
						let hour = i < 10 ? "0" + i : "" + i;
						value.push(hour + ":00");
					}

				} else{
					value = [
						"09:00",
						"10:00",
						"11:00",
						"12:00",
						"13:00",
						"14:00",
						"15:00",
						"16:00",
						"17:00",
						"18:00",
					]

				}
				return value;
			}
		},
		weekGround: {
			type: Array,
			default: [
				'Monday',
				'Tuesday',
				'Wednesday',
				'Thursday',
				'Friday'
			]
		},
		taskDetail: {
			type: Array,
			default: []
		},
		color: {
			type:...