#子コンポーネントから親コンポーネントで受けたデータをもとに条件をつけてリストを再表示させたい
現在、post.vue(子コンポーネント)にてinputタグで入力フォームを作成し、
そこで入力された値を$emitでboard.vue(親コンポーネント)に渡しています。(値を取得できていることは確認済)
通常投稿一覧に投稿されたpostを「時間(降順)」で表示させておりますが、
post.vue(子コンポーネント)から受けたデータをもとに「ジャンル」という値で絞って再表示させたいです。
※Firestoreのpostsコレクションのデータにはそれぞれgenreというフィールドに値は取得しております。
this.postDataの中身は以下のようになっております。
入力フォームで入力された値はpost.vue(子コンポーネント)より取得はできているので
あとは以下を行って表示させると思うのですが、どのように条件を絞ってあげたらいいのか分からない状況です。
- valueを引数に渡しているので、valueをもとにデータを絞る
- Firestore内のフィールド「genre」でデータを絞る
- postData内を一度クリアしてあげて再pushしてあげる
分かる方いらっしゃいましたらお力添えをいただきたいです。
よろしくお願いいたします。
#post.vue(子コンポーネント)
<input placeholder="例)アクション 恋愛 ミステリー SF ホラー ミュージカル etc.." class="search-main-item" type="search" @input="searchData($event.target.value)"/>
searchData(value) { this.$emit("searchData", value); }
#board.vue(親コンポーネント)
<template> <div> <Header /> <Post @searchData="search" /> <!--子コンポーネントから$emitで受けたデータを関数とする。※searchに()を付けるとvalueの引数が取れないので注意。--> <div class="post"> <h2 id="top" class="post-tll neon">投稿一覧</h2> <div class="post-inner"> <div class="post-items"> <paginate name="paginate-log" tag="ol" :list="postData" :per="12"> <List v-for="(list, index) in paginated('paginate-log')" :index="index" :list="list" :userDatas="userDatas" :key="list.id" /> </paginate> <paginate-links for="paginate-log" class="pagination flex" v-scroll-to="postTop" :show-step-links="true" ></paginate-links> <!--postDataのデータをlist関数とindex関数にそれぞれ格納--> </div> </div> </div> </div> </template>
export default { data() { return { title: "", contents: "", image: "", postData: [], paginate: ["paginate-log"], postTop: "#top", userDatas: [], }; }, components: { Header, Post, List }, methods: { search(value) { firebase .firestore() .collection("posts") .orderBy("genre") .orderBy("time", "desc") .get() .then(snapshot => { snapshot.forEach(doc => { this.postData.push({ ...doc.data(), id: doc.id }); }); }); } },
#追記1
以下はコードになります。
実際にタイプした時の画面になります。
入力したタイミングでリアルタイムで表示が切り替われば理想です。。
#追記2
以下のようにコードを書き替えましたので掲載させていただきます。
#board.vue(親コンポーネント)
html
1<template> 2 <div> 3 <Header /> 4 <Post v-model="searchWord" /> 5 <div class="post"> 6 <h2 id="top" class="post-tll neon">投稿一覧</h2> 7 <div class="post-inner"> 8 <div class="post-items"> 9 <paginate name="paginate-log" tag="ol" :list="filteredPostData" :per="12"> 10 <List 11 v-for="(list, index) in paginated('paginate-log')" 12 :index="index" 13 :list="list" 14 :userDatas="userDatas" 15 :key="list.id" 16 /> 17 </paginate> 18 <paginate-links 19 for="paginate-log" 20 class="pagination flex" 21 v-scroll-to="postTop" 22 :show-step-links="true" 23 ></paginate-links> 24 </div> 25 </div> 26 </div> 27 </div> 28</template>
js
1export default { 2 data() { 3 return { 4 title: "", 5 contents: "", 6 image: "", 7 postData: [], 8 paginate: ["paginate-log"], 9 postTop: "#top", 10 userDatas: [], 11 searchWord: "", 12 filteredPostData: [] 13 }; 14 }, 15 components: { 16 Header, 17 Post, 18 List 19 }, 20 computed: { 21 filteredPostData(value) { 22 console.log(value); 23 if (value != "") { 24 return this.postData.filter(v => { 25 return ~v.genre.indexOf(this.searchWord); 26 }); 27 } else { 28 return this.postData; 29 } 30 } 31 } 32 }, 33 created() { 34 // "posts"コレクションの全ドキュメントを取得。 35 firebase 36 .firestore() 37 .collection("posts") 38 .orderBy("time", "desc") 39 .get() 40 .then(snapshot => { 41 //"posts"(参照先)のスナップショットを得る 42 snapshot.forEach(doc => { 43 //上記で得たデータをforEachでドキュメントの数だけ"doc"データに格納 44 this.postData.push({ ...doc.data(), id: doc.id }); 45 //更にpostDataの空配列に格納した"doc"データを格納 46 }); 47 }); 48}; 49</script> 50
#post.vue(子コンポーネント)
html
1<div class="search-inner flex"> 2 <h2 class="search-tll neon flex">Cinemaryを検索する</h2> 3 <hr class="separate" /> 4 <div class="search-main-contens flex"> 5 <input 6 placeholder="例)アクション 恋愛 ミステリー SF ホラー ミュージカル etc.." 7 class="search-main-item" 8 type="search" 9 v-model="inputValue" 10 /> 11 </div>
js
1export default { 2 data() { 3 return { 4 5 ~ 省略 ~ 6 7}, 8 props: { 9 value: { 10 type: String, 11 required: true 12 } 13 }, 14 computed: { 15 inputValue: { 16 get() { 17 return this.value; 18 }, 19 set(value) { 20 this.$emit("input", value); 21 } 22 } 23 }, 24 searchData(value) { 25 this.$emit("searchData", value); 26 } 27 } 28}; 29
また、以下のようなエラーが出ておりまして調べてみましたが赤で囲った箇所のエラー内容で
objectとなっている原因が分からなかった為、エラー内容を追記いたします・・
[Vue warn]: Method "computed" has type "object" in the component definition. Did you reference the function correctly?
メソッド "computed" は、コンポーネント定義のタイプ "object" を持っています。関数を正しく参照しましたか?
青色括弧につきましては、 filteredPostDataをdata()内で初期化してくださいとのことでしたので、
data()内で filteredPostData: []と初期化しました。
#追記3
#追記4
###検索前
###検索後
###「t」を削除後
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/06 06:10
2021/06/06 07:46
2021/06/06 08:21 編集
2021/06/06 08:24
2021/06/06 09:41 編集
2021/06/06 09:44
2021/06/06 10:17
2021/06/07 02:55
2021/06/07 10:28
2021/06/07 11:02
2021/06/07 11:17
2021/06/07 11:32
2021/06/07 11:43
2021/06/07 11:45
2021/06/07 12:43
2021/06/07 13:10
2021/06/07 13:25
2021/06/07 13:29
2021/06/07 13:41