目的・ゴール
質問を見ててテーブル要素にデータを一覧として表示させてみたくなった
結果
暫定的にこうなった
表示させるのに都合のいいデータを用意したので、値はほぼ可変
<table/>
に表示させたい場合、サーバ側で、フロント側が表示しやすいようにデータの整形を頑張る必要があるのかもわからない
サーバとの連携については考えることができてない
機能は:
- 教科をクリックすると背景色が変わる
- 時間割の表示時間が現在時刻を過ぎているとクリック不能になる
というのを書いた
登場するコンポーネント
TimeTable.vue
:<table/>
を利用してデータの整形と表示をするToggleLabel.vue
: クリックすることで背景色を変える、チェックボックス付きのラベル
コンポーネントの内容
TimeTable.vue
:
<template> <div> <table> <tr> <td></td> <td v-for="date in timeTable.days">{{ date }}</td> </tr> <tr v-for="data in timeTable.reservationData" :key="data.time"> <td :class="expired(data.endTime)">{{ data.startTime }} ~ {{ data.endTime }}</td> <td v-for="v in data.value" :key="v"> <toggle-label :id="v + data.startTime" :expired="isExpired(data.endTime)"> {{ v }} </toggle-label> </td> </tr> </table> </div> </template> <script> import TableData from '@/components/TableData' import ToggleLabel from '@/components/ToggleLabel' let moment = require('moment') export default { name: 'TimeTable', data () { return { timeTable: { days: ['10/01', '10/02', '10/03', '10/04', '10/05', '10/06', '10/07'], reservationData: [ { 'startTime': '09:00', 'endTime': '10:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] }, { 'startTime': '10:00', 'endTime': '11:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] }, { 'startTime': '11:00', 'endTime': '12:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] }, { 'startTime': '12:00', 'endTime': '13:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] }, { 'startTime': '13:00', 'endTime': '14:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] }, { 'startTime': '14:00', 'endTime': '15:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] }, { 'startTime': '15:00', 'endTime': '16:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] }, { 'startTime': '16:00', 'endTime': '17:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] }, { 'startTime': '17:00', 'endTime': '18:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] }, { 'startTime': '18:00', 'endTime': '19:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] }, { 'startTime': '19:00', 'endTime': '20:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] }, { 'startTime': '20:00', 'endTime': '21:00', 'value': ['国語', '算数', '理科', '社会', '体育', '生活', '音楽'] } ] } } }, methods: { expired: function (v) { let timeFormat = 'HH::mm' // Not well tested but it may be worked. // let currentTime = moment(new Date(), timeFormat) // Fixed value for debug let currentTime = moment('12:00', timeFormat) let targetTime = moment(v, timeFormat) return ( targetTime.isBefore(currentTime) ? 'expired' : 'available' ) }, isExpired: function (v) { let format = 'HH::mm' // let currentTime = moment(new Date(), format) let currentTime = moment('12:00', format) let targetTime = moment(v, format) return targetTime.isBefore(currentTime) } }, components: { 'table-data': TableData, 'toggle-label': ToggleLabel } } </script> <style scoped> table { border: 2px solid #AAAAAA; } .expired { background: #A9A9A9; pointer-events: none; } </style>
ToggleLabel.vue
:
<template> <div> <input :id ="id" type="checkbox" :value="value"> <label :for="id" :class="isExpired"> <slot></slot> </label> </div> </template> <script> export default { name: 'ToogleLabel', data () { return {} }, props: { 'id': { 'type': String, 'default': '' }, 'expired': { 'type': Boolean, 'default': false }, 'value': { 'type': String, 'defualt': '' } }, computed: { isExpired: function () { return this.expired ? 'expired' : 'available' } } } </script> <style scoped> label { display: inline-block; padding: 3px 0px 3px 0px; width: 106%; } label.expired { background: #A9A9A9; pointer-events: none; } input { display: none; } :checked + label { background: #CEFECE; } </style>