質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

Vuex

Vuexは、Vue.js アプリケーションのための状態管理ライブラリです。アプリケーション内で使用するコンポーネントのための集中データストアを提供。コンポーネント同士でデータをやり取りし、処理のフローを一貫させたり、データの見通しを良くすることができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1739閲覧

Vue.js カレンダーアプリ タスク追加した日付にのみ <span>タスク内容</span> を動的に追加したい

tkmvictim

総合スコア2

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

Vuex

Vuexは、Vue.js アプリケーションのための状態管理ライブラリです。アプリケーション内で使用するコンポーネントのための集中データストアを提供。コンポーネント同士でデータをやり取りし、処理のフローを一貫させたり、データの見通しを良くすることができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/08/26 14:00

前提・実現したいこと

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">&laquo;</th> 7 <th id="title" colspan="5">{{getTitleDate}}</th> 8 <th id="next" @click="nextPage">&raquo;</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')

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

v-ifで日付一致を条件にすることでタスクがある日付にだけhtmlタグを出力することが出来ました

投稿2020/08/27 07:21

tkmvictim

総合スコア2

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問