#ブックマーク機能にて「保存」と「削除」と条件に応じて切り替えたい
現状list.vueにて以下のように左下のボタンを用意して、それぞれsaveBookmark()とdeleteBookmark()を作成し、並べている状態です。
#実際のソース
####bookmark.vue(親コンポーネント)
<List v-for="(list) in paginated('paginate-bookmarkList')" :list="list" :key="list.id" /> <!-- data内にあるbookmarkList配列から、v-forディレクティブを使って1つずつ要素を取り出し描画。 -->
export default { data() { return { profileData: {}, paginate: ["paginate-bookmarkList"], bookmarkList: [], currentUserBookmarkIds: [], uid: null }; }, components: { Header, List }, created() { firebase .firestore() .collection("users") .doc(this.$route.params.uid) .get() .then(snapshot => { this.profileData = snapshot.data(); }); //各ユーザー(ページ内のユーザー)がブックマークしたリスト firebase .firestore() .collection("users") .doc(this.$route.params.uid) .collection("bookmarks") .orderBy("time", "desc") .get() .then(snapshot => { snapshot.forEach(doc => { this.bookmarkList.push(doc.data()); }); }); //ログイン中ユーザーがブックマークしたリスト firebase.auth().onAuthStateChanged(user => { const uid = user.uid; firebase .firestore() .collection("users") //「users」コレクションを参照 .doc(uid) //ログイン中のユーザーを参照 .collection("bookmarks") //「bookmarks」サブコレクションを参照 .get() .then(snapshot => { snapshot.forEach(doc => { //forEachで全てのドキュメントに対して this.currentUserBookmarkIds.push(doc.data().postId); //「postId」を追加し、this.currentUserBookmarkIdsへ格納 }); }); firebase .firestore() .collection("posts") //「posts」コレクションを参照 .get() .then(snapshot => { snapshot.forEach(doc => { //forEachで全てのドキュメントに対して if (this.currentUserBookmarkIds.includes(doc.data().id)) { //this.currentUserBookmarkIdsに「id」が含まれていたら、 this.bookmarkList.push({ ...doc.data(), isBookmarked: true }); console.log(this.bookmarkList); //...doc.data()としてバラした「posts」の投稿データとisBookmarkedを代入。 } }); }); }); } };
####list.vue(子コンポーネント)
<template> <div class="list"> <div class="face face1 flex"> <div class="content"> <img class="profile-icon" width="50" height="50" :src=" returnUserData() ? returnUserData().uploadedImage.fileUrl : preview " /> <h3>{{ list.title }}</h3> </div> </div> <div class="face face2 flex"> <div class="content flex"> <button class="hide-btn" @click="deletePost">×</button> <p>{{ list.description }}</p> <router-link :to="`/chat/${list.id}`" class="join-btn flex">ルームへ参加</router-link> <!-- 「list.id」propsで親コンポーネントから取得したidを取得。--> <img src="../assets/ブックマーク保存.jpg" alt="ブックマーク" class="bookmark-icon" @click="saveBookmark" v-if="hasBookmark(list)" /> <img src="../assets/ブックマーク未保存.jpg" alt="ブックマーク" class="bookmark-icon" @click="deleteBookmark" v-else /> <p class="post-time">{{ list.time.toDate().toLocaleString() }}</p> </div> </div> </div> </template>
export default { data() { return { bookmarkId: "", userDatas: [], preview: require("../assets/デフォルト画像.jpg") }; }, props: { list: { type: Object }, index: { type: Number }, }, methods: { ~ 省略 ~ hasBookmark(book) { // ブックマークリスト内にbook idがあればtrue それ以外はfalse return this.bookmark.some(value => value.id === book.id); }, saveBookmark() { const id = firebase .firestore() .collection("users") .doc(this.$route.params.uid) .collection("bookmarks") .doc().id; firebase .firestore() .collection("users") //「users」コレクションを参照 .doc(this.$route.params.uid) //対象ページのユーザーを参照 .collection("bookmarks") //「bookmarks」サブコレクションを参照 .doc(id) //自動生成されたドキュメントIDを参照 .set( { postId: this.list.id, //「postId」に投稿データである「this.list.id」を代入。 time: firebase.firestore.FieldValue.serverTimestamp() } ) .then(() => { this.$swal("ブックマークに追加しました。", { icon: "success" }); }) .catch(() => { this.$swal("ブックマークを追加出来ません。", { icon: "error" }); }); }, deleteBookmark() { firebase .firestore() .collection("users") .doc(this.$route.params.uid) .collection("bookmarks") .doc(this.list.postId) .delete() .then(() => { this.$swal("ブックマークを取り消ししました。", { icon: "success" }); this.$router.go({ path: `/bookmark/${this.$route.params.uid}`, force: true }); }) .catch(() => { this.$swal("ブックマークを取り消し出来ません。", { icon: "error" }); }); },
#追記 「内容整理」
####⑴bookmark.vueにてブックマークされた一覧を表示する際について。
ブックマーク保存(savebookmark)する際、投稿(list)のidをサブコレクションのbookmarksへ「postId」としてデータを保存してあげて、
そのブックマークされた際に取得した「postId」と投稿時に取得する「id」が一致されたものをブックマーク一覧に表示させています。
◆投稿時に取得する「id」
◆ブックマークされた際に取得した「postId」
しかし、以下2点でthis.bookmarkListに追加しているからなのか、一つの投稿をブックマークすると2つの投稿が表示されてしまいます。
####各ユーザー(ページ内のユーザー)がブックマークしたリスト
firebase .firestore() .collection("users") .doc(this.$route.params.uid) .collection("bookmarks") .orderBy("time", "desc") .get() .then(snapshot => { snapshot.forEach(doc => { this.bookmarkList.push(doc.data()); }); });
####ログイン中ユーザーがブックマークしたリスト
firebase.auth().onAuthStateChanged(user => { const uid = user.uid; firebase .firestore() .collection("users") //「users」コレクションを参照 .doc(uid) //ログイン中のユーザーを参照 .collection("bookmarks") //「bookmarks」サブコレクションを参照 .get() .then(snapshot => { snapshot.forEach(doc => { //forEachで全てのドキュメントに対して this.currentUserBookmarkIds.push(doc.data().postId); //「postId」を追加し、this.currentUserBookmarkIdsへ格納 }); }); firebase .firestore() .collection("posts") //「posts」コレクションを参照 .get() .then(snapshot => { snapshot.forEach(doc => { //forEachで全てのドキュメントに対して if (this.currentUserBookmarkIds.includes(doc.data().id)) { //this.currentUserBookmarkIdsに「id」が含まれていたら、 this.bookmarkList.push({ ...doc.data(), isBookmarked: true }); console.log(this.bookmarkList); //...doc.data()としてバラした「posts」の投稿データとisBookmarkedを代入。 } }); }); }); }
単純に「各ユーザー(ページ内のユーザー)がブックマークしたリスト」を消したらいいのかと思ったのですが、消すと他のユーザーのブックマーク一覧を閲覧した際にそのユーザーのブックマーク一覧を表示するのではなく、ログイン中のユーザーのブックマーク一覧を表示してしまいます・・
他のユーザーのブックマークを閲覧した際にはそのユーザーのブックマーク一覧を表示して、被らずに1枚のみを表示したいです。
#⑵投稿の中にisBookmarkedとしてブックマークされている投稿かどうかが判定したい。
※以下赤で囲っている箇所参照
ブックマークされている投稿かどうかが判定できる情報「isBookmarked」を一緒に渡してあげているので、listコンポーネント側で、isBookmarkedがtrue,かfalseかで表示を変えてあげようと考えておりますが、以下について悩んでおります。
propsで子コンポーネントであるlist.vueにデータを渡し、「isBookmarked」がtrue,かfalseか確認すればよろしいのでしょうか。
もしくはFirestore内に「isBookmarked」を保存してあげたほうがよいのでしょうか。
またlist.vue側でどのように「isBookmarked」がtrue,かfalseか判定してあげたらよいのか分からない状況です・・
#⑶board.vue「投稿一覧」からでもブックマークの「保存」と「削除」を行えるようにしたい
board.vueコンポーネントでも同様に、ログインしているユーザーのブックマーク一覧から、それに紐づいたpostIdを持つ投稿を取り出してきて、それにisBookmarkedをつけてあげてboard.vue側でもブックマークの保存と削除を行えるようにしたいと考えております。
export default { data() { return { currentUserBookmarkIds: [], uid: null }; }, //各ユーザーがブックマークしたリスト firebase .firestore() .collection("users") //「users」コレクションを参照 .doc(this.$route.params.uid) //現在表示中ユーザーを参照 .collection("bookmarks") //「bookmarks」サブコレクションを参照 .get() .then(snapshot => { snapshot.forEach(doc => { //forEachで全てのドキュメントに対して this.currentUserBookmarkIds.push(doc.data().postId); //「postId」を追加し、this.currentUserBookmarkIdsへ格納 }); }); firebase .firestore() .collection("posts") //「posts」コレクションを参照 .orderBy("time", "desc") .get() .then(snapshot => { snapshot.forEach(doc => { //forEachで全てのドキュメントに対して if (this.currentUserBookmarkIds.includes(doc.data().id)) { //this.currentUserBookmarkIdsに「id」が含まれていたら、 this.postData.push({ isBookmarked: true }); //isBookmarkedを追加。 } }); }); }
以上bookmark.vueと同様の方法でisBookmarked: trueをpushしてあげようと考えていますが、こちらにつきましても⑵同様にpropsでデータを渡すかFirestore内に保存してあげたらよいのか悩んでいる状況です。
ご教示頂けると幸いです。。
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/10 15:22
2021/06/10 15:27
2021/06/10 15:38
2021/06/10 15:48
2021/06/10 16:15
2021/06/10 21:33
2021/06/10 23:21
2021/06/11 10:07
2021/06/11 12:20
2021/06/12 02:38
2021/06/12 02:42 編集
2021/06/12 02:57
2021/06/12 03:00
2021/06/12 03:19
2021/06/12 03:28
2021/06/12 03:43 編集
2021/06/12 03:48
2021/06/12 03:55
2021/06/12 16:13 編集
2021/06/14 08:55
2021/06/14 10:02
2021/06/14 10:08
2021/06/18 16:06
2021/06/19 11:38
2021/06/19 12:07 編集
2021/06/22 23:03
2021/06/23 00:56