前提・実現したいこと
vueとfirestoreで、簡単なタスク管理システムを作っています。
主に下記のような機能があります。
0. ログイン
0. サインアップ
0. ログアウト
0. [問題箇所!] タスクリストのリアルタイム表示
0. 追加・削除
発生している問題
ポイント:
- 最初に表示されるデータは、問題なし
- 追加 / 削除が実行されると、しっかりリアルタイムに反映される
- だが追加 / 削除前のリストの状態も消えずに残る。。。
リアルタイム表示機能は主に2つのファイルから構成
0. projectList.vue:タスクリストを表示させるコンポーネント
0. projectCard.vue:各タスク情報を表示するコンポーネント
該当のソースコード:projectList.vue リストのリアルタイム表示
vue
1<template> 2 <div class="projectList"> 3 <button class="home-buttons" @click="newProject">Add project</button> 4 <div v-if="createNew"> 5 <projectAdd/> 6 </div> 7 <div v-show="loading"> 8 <Loader/> 9 </div> 10 <div v-show="!loading"> 11 12 <!--03 ここで取得したデータをprojectCard.vueへ渡し、リスト表示させます--> 13 <projectCard v-for="project in projects" :key="project.id" :project="project"/> 14 15 </div> 16 <p v-show="noproject">There is no project</p> 17 </div> 18 19</template> 20 21<script> 22import firebase from '@/firebase/firestore'; 23import Loader from '@/components/loading.vue'; 24import projectCard from '@/components/projectCard.vue'; 25import projectAdd from '@/components/addProject.vue'; 26 27export default { 28 components: { 29 projectCard, 30 Loader, 31 projectAdd, 32 }, 33 data() { 34 return { 35 userid: this.$route.params.userId, 36 37 //02 ここに取得したデータが格納されます 38 projects: [], 39 40 loading: true, 41 createNew: false, 42 }; 43 }, 44 created() { 45 //01 データをリアルタイムに取得し、projectsに渡す 46 const db = firebase.firestore() 47 .collection('user') 48 .doc(this.userid) //$route.params.userId 49 .collection('projects') 50 .orderBy('createdAt', 'desc'); 51 db 52 .onSnapshot((querySnapshot) => { 53 querySnapshot.forEach((doc) => { 54 this.projects.push(doc.data()); 55 }); 56 if (this.projects.length >= 0) { 57 this.loading = false; 58 } else if (this.projects.length <= 0) { 59 this.loading = false; 60 } 61 }); 62 }, 63 methods: { 64 newProject() { 65 if (this.createNew !== true) { 66 this.createNew = true; 67 } else { 68 this.createNew = false; 69 } 70 }, 71 }, 72}; 73</script> 74
該当のソースコード:projectCard.vue 各タスクデータの受け皿
vue
1<template> 2 <div class="projectCard"> 3 <div class="user-list"> 4 <div class="columns"> 5 <div class="column is-8"> 6 <h3>{{ project.projectname }}</h3> 7 <p>{{ project.slug }}</p> 8 <p>Why : {{ project.why }}</p> 9 <p>{{ project.phase }}</p> 10 </div> 11 <div class="column is-4 right"> 12 <router-link class="button is-primary" :to="{ name: 'viewproject', params: { projectId: project.slug }}"> 13 Find out more! 14 </router-link> 15 <button @click="deleteProject"> Delete </button> 16 </div> 17 </div> 18 </div> 19 </div> 20</template> 21 22<script> 23import firebase from '@/firebase/firestore'; 24 25export default { 26 name: 'ProjectCard', 27 props: { 28 // ここは親コンポーネントであるprojectList.vueから渡されたデータが格納されている(はず?) 29 project: Object, 30 }, 31 methods: { 32 //タスクの削除 33 deleteProject() { 34 firebase.firestore().collection('user').doc(this.project.userId) 35 .collection('projects') 36 .where('slug', '==', this.project.slug) 37 .get() 38 .then((snapshot) => { 39 snapshot.forEach((doc => { 40 console.log(doc.data().slug); 41 doc.ref.delete(); 42 alert('You have deleted the project!' + doc.data().slug); 43 })) 44 }) 45 }, 46 }, 47 48}; 49 50</script> 51 52<style lang="scss" scoped> 53 h1 { 54 font-size: 30px; 55 margin: 30px 0; 56 } 57 .user-list { 58 text-align: center; 59 margin-top: 30px; 60 background-color: rgb(252, 252, 252); 61 padding: 20px; 62 box-shadow: 0 0 5px 0 rgba(0,0,0,0.05); 63 .column { 64 height: 95px; 65 } 66 .inner { 67 .left { 68 width: 50%; 69 float: left; 70 text-align: left; 71 } 72 .right { 73 width: 50%; 74 float: left; 75 text-align: left; 76 p { 77 width: 100%; 78 text-align: left; 79 } 80 } 81 } 82 .right { 83 display: flex; 84 align-items: center; 85 justify-content: center; 86 button { 87 background: #4B75FF; 88 } 89 } 90 .user-list__header { 91 font-size: 20px; 92 font-weight: 700; 93 } 94 .user-list__sub { 95 font-size: 15px; 96 margin-top: 10px; 97 } 98 } 99</style> 100
試したこと
ページを手動でリフレッシュすれば、更新前の状態は消えて、タスクリストは正常に表示されます。
ですが、せっかくリアルタイムに反映させる機能を追加したのに、、、と思ってしまいます。。。
set Vue() new Vue()で解決できるという記事をみて試したのですが、うまく行かず。。。
どなたか、是非ご教授お願いいたします!
補足情報:タスク追加のソースコード
タスク追加は主に2つのファイルから構成
0. addProject.vue : projectList.vue内で表示
0. addProject.js
addProject.vue:追加するタスクを入力するコンポーネント
vue
1<template> 2 <div id="addProject"> 3 <div class="user-list"> 4 <div class="columns"> 5 <div class="column is-8"> 6 <form @submit.prevent="saveContact"> 7 <div class="field"> 8 <label class="label">Project Name</label> 9 <div class="control"> 10 <input v-model="projectname" class="input" type="text" placeholder="Project Name" required> 11 </div> 12 </div> 13 14 <div class="field"> 15 <label class="label">Why do you work on this?</label> 16 <div class="control"> 17 <textarea v-model="why" class="input" placeholder="Why?" required /> 18 </div> 19 </div> 20 21 <div class="field"> 22 <label class="label">Where are you at?</label> 23 <div class="control"> 24 <select v-model="phase" required> 25 <option disabled value=""> 26 Project Stage 27 </option> 28 <option>A</option> 29 <option>B</option> 30 <option>C</option> 31 </select> 32 </div> 33 </div> 34 <div class="field"> 35 <div class="control"> 36 <button @click="add"> 37 Add Project! 38 </button> 39 </div> 40 </div> 41 </form> 42 </div> 43 </div> 44 </div> 45 </div> 46</template> 47 48<script> 49import firebase from '@/firebase/firestore'; 50import addProject from '@/js/addProject.js'; 51 52export default { 53 name: 'NewProject', 54 data() { 55 return { 56 createdAt: new Date(), 57 userId: firebase.auth().currentUser.uid, 58 projectname: null, 59 why: null, 60 phase: null, 61 }; 62 }, 63 methods: { 64 add() { 65 addProject.addProject(this.createdAt, this.userId, this.projectname, this.why, this.phase); 66 }, 67 }, 68}; 69</script> 70 71<style lang="scss" scoped> 72#addProject{ 73 text-align: center; 74 margin-top: 65px; 75} 76h1 { 77 font-size: 30px; 78 margin: 30px 0; 79 } 80 .user-list { 81 text-align: center; 82 margin-top: 30px; 83 background-color: rgb(252, 252, 252); 84 padding: 20px; 85 box-shadow: 0 0 5px 0 rgba(0,0,0,0.05); 86 .column { 87 height: 195px; 88 } 89 .inner { 90 .left { 91 width: 50%; 92 float: left; 93 text-align: left; 94 } 95 .right { 96 width: 50%; 97 float: left; 98 text-align: left; 99 p { 100 width: 100%; 101 text-align: left; 102 } 103 } 104 } 105 .right { 106 display: flex; 107 align-items: center; 108 justify-content: center; 109 button { 110 background: #4B75FF; 111 } 112 } 113 .user-list__header { 114 font-size: 20px; 115 font-weight: 700; 116 } 117 .user-list__sub { 118 font-size: 15px; 119 margin-top: 10px; 120 } 121 } 122</style>
addProject.js:Firesotreに追加データを送る機能
js
1import firebase from '@/firebase/firestore'; 2 3export default { 4 addProject(createdAt, userId,projectname,why,phase){ 5 const db = firebase.firestore().collection("user") 6 .doc(userId).collection("projects"); // "Project"という名前のコレクションへの参照を作成 7 db.add({ 8 createdAt: createdAt, 9 userId: userId, 10 projectname: projectname, 11 why: why, 12 phase: phase, 13 slug: this.generateUUID(), 14 }) 15 .then(function (docRef) { 16 console.log('Document written with ID: ', docRef.id); 17 alert('Well done! You have created a new project!'); 18 }) 19 .catch(function (error) { 20 console.error('Error adding document: ', error); 21 }); 22 }, 23 generateUUID() { 24 let d = new Date().getTime(); 25 let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 26 let r = (d + Math.random() * 16) % 16 | 0; 27 d = Math.floor(d / 16); 28 return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); 29 }); 30 return uuid; 31 }, 32};
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。