前提・実現したいこと
googleカレンダーのようなアプリを作成しており、tr, tdタグにv-forディレクティブを使いカレンダーとタスク内容を出力しています。
カレンダーが持つ日付のデータとタスク登録する際に持たせた日付データが一致する場合にタスク内容を反映するようにしているのですが、<span :key="task.id">{{task.date === day.fullDate ? task.name : ''}}</span>
でタスクを出力している為、一致するタスクがない場合でも空のspanタグが出力されてしまいます。
日付情報が一致する場合のみ<span>タスク内容</span>を<td>日付</td>の中に挿入するようにしたいのですがどうすればよいでしょう?
該当のソースコード
JavaScript
1<template> 2 <div class="calendar-wrapper example-modal-window"> 3 <table> 4 <thead> 5 <tr> 6 <th id="prev" @click="prevPage">«</th> 7 <th id="title" colspan="5">{{getTitleDate}}</th> 8 <th id="next" @click="nextPage">»</th> 9 </tr> 10 <tr> 11 <th>Sun</th> 12 <th>Mon</th> 13 <th>Tue</th> 14 <th>Wed</th> 15 <th>Thu</th> 16 <th>Fri</th> 17 <th>Sat</th> 18 </tr> 19 </thead> 20 <tbody> 21 <tr v-for="(week, index) in createCalendar" :key="index"> 22 <td 23 v-for="day in week" 24 :key="day.fullDate" 25 :class="{disabled: day.isDisabled, today: day.isToday}" 26 @click="openModal(day.fullDate)" 27 > 28 {{day.date}} 29 <br /> 30 <div class="taskList"> 31 <template 32 v-for="task in taskList" 33 @click.stop="openEditModal(task.id)" 34 ><span :key="task.id">{{task.date === day.fullDate ? task.name : ''}}</span></template> 35 </div> 36 </td> 37 </tr> 38 </tbody> 39 </table> 40 <!-- 新規追加用モーダル --> 41 <my-modal @close="closeModal" v-if="modal"> 42 <p>タスクを入力してください</p> 43 <div> 44 <input type="text" v-model="message" /> 45 </div> 46 <template slot="footer"> 47 <button @click="doSend">送信</button> 48 </template> 49 </my-modal> 50 <!-- 編集用モーダル --> 51 <my-modal @close="closeModal" v-if="editModal"> 52 <button @click="deleteTask(taskId)">削除</button> 53 <p>タスクを入力してください</p> 54 <div> 55 <input type="text" v-model="editMessage" /> 56 </div> 57 <template slot="footer"> 58 <button @click="doEdit()">送信</button> 59 </template> 60 </my-modal> 61 </div> 62</template> 63 64<script> 65import MyModal from "./MyModal.vue"; 66 67export default { 68 components: { 69 MyModal, 70 }, 71 data() { 72 return { 73 month: "", 74 year: "", 75 today: "", 76 modal: false, 77 editModal: false, 78 message: "", 79 editMessage: "", 80 fullDate: "", 81 taskId: null 82 }; 83 }, 84 created() { 85 this.today = new Date(); 86 87 this.year = this.today.getFullYear(); 88 // 0 ~ 11 89 this.month = this.today.getMonth(); 90 }, 91 computed: { 92 createCalendar() { 93 const dates = [ 94 ...this.getCalendarHead, 95 ...this.getCalendarBody, 96 ...this.getCalendarTail, 97 ]; 98 // 一週間ごとのオブジェクトが配列にまとめて入っている 99 const weeks = []; 100 const weeksCount = dates.length / 7; 101 102 for (let i = 0; i < weeksCount; i++) { 103 weeks.push(dates.splice(0, 7)); 104 } 105 106 return weeks; 107 }, 108 109 getTitleDate() { 110 return `${this.year}/${String(this.month + 1).padStart(2, "0")}`; 111 }, 112 113 getCalendarHead() { 114 const dates = []; 115 const d = new Date(this.year, this.month, 0).getDate(); 116 const n = new Date(this.year, this.month, 1).getDay(); 117 118 for (let i = 0; i < n; i++) { 119 dates.unshift({ 120 date: d - i, 121 isToday: false, 122 isDisabled: true, 123 fullDate: `${this.year}_${String(this.month).padStart( 124 2, 125 "0" 126 )}_${String(d - i).padStart(2, "0")}`, 127 }); 128 } 129 130 return dates; 131 }, 132 133 getCalendarBody() { 134 const dates = []; // date: 日付, day: 曜日 135 const lastDate = new Date(this.year, this.month + 1, 0).getDate(); 136 137 for (let i = 1; i <= lastDate; i++) { 138 dates.push({ 139 date: i, 140 isToday: false, 141 isDisabled: false, 142 fullDate: `${this.year}_${String(this.month + 1).padStart( 143 2, 144 "0" 145 )}_${String(i).padStart(2, "0")}`, 146 }); 147 } 148 // 年月がthis.todayと一致するとき実行 149 if ( 150 this.year === this.today.getFullYear() && 151 this.month === this.today.getMonth() 152 ) { 153 // dates配列は0から始まる 154 dates[this.today.getDate() - 1].isToday = true; 155 } 156 157 return dates; 158 }, 159 160 getCalendarTail() { 161 const dates = []; 162 const lastDay = new Date(this.year, this.month + 1, 0).getDay(); 163 164 for (let i = 1; i < 7 - lastDay; i++) { 165 dates.push({ 166 date: i, 167 isToday: false, 168 isDisabled: true, 169 fullDate: `${this.year}_${String(this.month + 2).padStart( 170 2, 171 "0" 172 )}_${String(i).padStart(2, "0")}`, 173 }); 174 } 175 176 return dates; 177 }, 178 179 taskList() { 180 return this.$store.getters.taskList; 181 }, 182 183 getTaskMessage() { 184 const editTask = this.taskList.filter(task => task.id === this.taskId)[0] 185 return editTask 186 } 187 }, 188 methods: { 189 prevPage() { 190 this.month--; 191 if (this.month < 0) { 192 this.year--; 193 this.month = 11; 194 } 195 }, 196 nextPage() { 197 this.month++; 198 if (this.month > 11) { 199 this.year++; 200 this.month = 0; 201 } 202 }, 203 openModal(value) { 204 this.modal = true; 205 // doSendでmutationに渡すのに使う 206 this.fullDate = value; 207 }, 208 openEditModal(taskId) { 209 this.editModal = true; 210 this.taskId = taskId; 211 console.log(this.taskId) 212 this.editMessage = this.getTaskMessage.name 213 }, 214 closeModal() { 215 this.modal = false; 216 this.editModal = false; 217 }, 218 doSend() { 219 if (this.message.length > 0) { 220 this.$store.commit("addTask", { 221 message: this.message, 222 date: this.fullDate, 223 }); 224 this.message = ""; 225 this.closeModal(); 226 } else { 227 alert("タスクを入力してください"); 228 } 229 }, 230 doEdit() { 231 if (this.editMessage.length > 0) { 232 this.$store.commit("editTask", { 233 editMessage: this.editMessage, 234 taskId: this.taskId, 235 }); 236 this.editMessage = ""; 237 this.closeModal(); 238 } else { 239 alert("タスクを入力してください"); 240 } 241 }, 242 deleteTask(id) { 243 if (!confirm('このタスクを削除しますか?')) { 244 return 245 } 246 this.$store.commit('deleteTask', {id}) 247 this.editModal = false; 248 } 249 }, 250}; 251</script>
JavaScript
1import Vue from 'vue' 2import Vuex from 'vuex' 3import App from './App.vue' 4 5Vue.use(Vuex) 6 7const store = new Vuex.Store({ 8 state: { 9 tasks: [ 10 { 11 id: 1, 12 name: 'Vue.jsの勉強をする', 13 date: '2020_08_22' 14 }, 15 { 16 id: 2, 17 name: 'ご飯を食べる', 18 date: '2020_09_03' 19 } 20 ], 21 22 nextTaskId: 3 23 }, 24 getters: { 25 taskList: state => { 26 return state.tasks 27 } 28 }, 29 mutations: { 30 addTask(state, payload) { 31 state.tasks.push({ 32 id: state.nextTaskId, 33 name: payload.message, 34 date: payload.date 35 }) 36 37 state.nextTaskId++ 38 }, 39 editTask(state, payload) { 40 const task = state.tasks.find(task => task.id === payload.taskId) 41 task.name = payload.editMessage 42 }, 43 deleteTask(state, payload) { 44 const task = state.tasks.filter(task => task.id !== payload.id) 45 state.tasks = task 46 } 47 } 48}) 49 50Vue.config.productionTip = false 51 52new Vue({ 53 store, 54 render: h => h(App), 55}).$mount('#app')
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。