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

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

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

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

Google カレンダー

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

Vuex

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

Vue CLI

Vue CLIは、Vue.jsでアプリケーション開発を行うためのコマンドラインインタフェース(CLI)に基づいた開発ツールです。インタラクティブなプロジェクトの雛形や設定なしで使用できるプロトタイプの作成など、さまざまな機能が用意されています。

JavaScript

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

Q&A

解決済

1回答

1385閲覧

Vue.js Vuexを使ったタスク管理カレンダーでVuexへのタスク追加をカレンダーに反映させたい

tkmvictim

総合スコア2

Vue.js

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

Google カレンダー

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

Vuex

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

Vue CLI

Vue CLIは、Vue.jsでアプリケーション開発を行うためのコマンドラインインタフェース(CLI)に基づいた開発ツールです。インタラクティブなプロジェクトの雛形や設定なしで使用できるプロトタイプの作成など、さまざまな機能が用意されています。

JavaScript

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

0グッド

0クリップ

投稿2020/08/25 14:38

前提・実現したいこと

Vue.js Vuexを使ったカレンダーにタスクを追加出来るアプリを開発しているのですが、Vuexに追加したタスクを即座にカレンダーに反映したいです

発生している問題・エラーメッセージ

日付ごとに<td></td>をリストレンダリングしてカレンダーを作成して行きつつ、methodsプロパティ内にあるgetMessageTextメソッドによって日付オブジェクトごとに与えられた年月日(例: 2020_08_22)の値と一致する日付を持つタスクがステート内に存在する場合、<td></td>内に、<span>タスク内容</span>の形で挿入して反映しています。

新たにストアのtasks配列にフォームを通じてデータをコミットした際、リストレンダリングを再描画させ、タスクをカレンダーに反映させたいのですが上手い方法が見つからず攻めあぐねています

JavaScript

1getMessageText(calendarDate) { 2 for (let i = 0; i < this.tasks.length; i++) { 3 const message = this.tasks.filter(date => date.date === calendarDate)[0] 4 return message ? message.name : '' 5 } 6}

該当のソースコード

JavaScript(Calendar.vue)

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><span>{{getMessageText(day.fullDate)}}</span> 30 </td> 31 </tr> 32 </tbody> 33 </table> 34 <my-modal @close="closeModal" v-if="modal"> 35 <p>タスクを入力してください</p> 36 <div><input type="text" v-model="message"></div> 37 <template slot="footer"> 38 <button @click="doSend">送信</button> 39 </template> 40 </my-modal> 41 </div> 42</template> 43 44<script> 45import MyModal from './MyModal.vue' 46 47export default { 48 components: { 49 MyModal 50 }, 51 data() { 52 return { 53 month: "", 54 year: "", 55 today: "", 56 modal: false, 57 message: '', 58 fullDate: '' 59 }; 60 }, 61 created() { 62 this.today = new Date(); 63 64 this.year = this.today.getFullYear(); 65 // 0 ~ 11 66 this.month = this.today.getMonth(); 67 }, 68 computed: { 69 createCalendar() { 70 const dates = [ 71 ...this.getCalendarHead, 72 ...this.getCalendarBody, 73 ...this.getCalendarTail, 74 ]; 75 // 一週間ごとのオブジェクトが配列にまとめて入っている 76 const weeks = []; 77 const weeksCount = dates.length / 7; 78 79 for (let i = 0; i < weeksCount; i++) { 80 weeks.push(dates.splice(0, 7)); 81 } 82 83 return weeks; 84 }, 85 86 getTitleDate() { 87 return `${this.year}/${String(this.month + 1).padStart(2, "0")}`; 88 }, 89 90 getCalendarHead() { 91 const dates = []; 92 const d = new Date(this.year, this.month, 0).getDate(); 93 const n = new Date(this.year, this.month, 1).getDay(); 94 95 for (let i = 0; i < n; i++) { 96 dates.unshift({ 97 date: d - i, 98 isToday: false, 99 isDisabled: true, 100 fullDate: `${this.year}_${String(this.month).padStart(2, '0')}_${String(d - i).padStart(2, '0')}`, 101 }); 102 } 103 104 return dates; 105 }, 106 107 getCalendarBody() { 108 const dates = []; // date: 日付, day: 曜日 109 const lastDate = new Date(this.year, this.month + 1, 0).getDate(); 110 111 for (let i = 1; i <= lastDate; i++) { 112 dates.push({ 113 date: i, 114 isToday: false, 115 isDisabled: false, 116 fullDate: `${this.year}_${String(this.month + 1).padStart(2, '0')}_${String(i).padStart(2, '0')}`, 117 }); 118 } 119 // 年月がthis.todayと一致するとき実行 120 if ( 121 this.year === this.today.getFullYear() && 122 this.month === this.today.getMonth() 123 ) { 124 // dates配列は0から始まる 125 dates[this.today.getDate() - 1].isToday = true; 126 } 127 128 return dates; 129 }, 130 131 getCalendarTail() { 132 const dates = []; 133 const lastDay = new Date(this.year, this.month + 1, 0).getDay(); 134 135 for (let i = 1; i < 7 - lastDay; i++) { 136 dates.push({ 137 date: i, 138 isToday: false, 139 isDisabled: true, 140 fullDate: `${this.year}_${String(this.month + 2).padStart(2, '0')}_${String(i).padStart(2, '0')}`, 141 }); 142 } 143 144 return dates; 145 }, 146 147 tasks() { 148 return this.$store.state.tasks 149 }, 150 }, 151 methods: { 152 prevPage() { 153 this.month--; 154 if (this.month < 0) { 155 this.year--; 156 this.month = 11; 157 } 158 }, 159 nextPage() { 160 this.month++; 161 if (this.month > 11) { 162 this.year++; 163 this.month = 0; 164 } 165 }, 166 openModal(value) { 167 this.modal = true 168 this.fullDate = value 169 }, 170 closeModal() { 171 this.modal = false 172 }, 173 doSend() { 174 if(this.message.length > 0) { 175 this.$store.commit('addTask', {message: this.message, date: this.fullDate}) 176 this.message = '' 177 this.closeModal() 178 } else { 179 alert('タスクを入力してください') 180 } 181 }, 182 getMessageText(calendarDate) { 183 for (let i = 0; i < this.tasks.length; i++) { 184 const message = this.tasks.filter(date => date.date === calendarDate)[0] 185 return message ? message.name : '' 186 } 187 } 188 }, 189}; 190</script> 191 192<style scoped> 193.calendar-wrapper { 194 height: 100vh; 195} 196 197table { 198 border-collapse: collapse; 199 border: 2px solid #eeeeee; 200 width: 100%; 201 height: 100%; 202 table-layout: fixed; 203} 204 205thead { 206 background: #eeeeee; 207} 208 209th, 210td { 211 padding: 8px; 212 text-align: center; 213 height: 50px; 214 border: 1px solid #eeeeee; 215} 216 217td { 218 vertical-align: top; 219} 220 221tbody td:first-child { 222 color: red; 223} 224 225tbody td:last-child { 226 color: blue; 227} 228 229td.disabled { 230 opacity: 0.3; 231} 232 233td.today { 234 font-weight: bold; 235} 236 237#prev, 238#next, 239#today { 240 cursor: pointer; 241 user-select: none; 242} 243</style>

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 mutations: { 25 addTask(state, payload) { 26 state.tasks.push({ 27 id: state.nextTaskId, 28 name: payload.message, 29 fullDate: payload.date 30 }) 31 console.log(state.tasks) 32 33 state.nextTaskId++ 34 } 35 } 36}) 37 38Vue.config.productionTip = false 39 40new Vue({ 41 store, 42 render: h => h(App), 43}).$mount('#app') 44

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

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

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

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

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

guest

回答1

0

自己解決

mutationする際の日付情報のプロパティ名とリストレンダリングする際のプロパティ名が一致していないのが原因でした

投稿2020/08/25 16:44

tkmvictim

総合スコア2

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問