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

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

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

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

Vue CLI

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

Q&A

1回答

1338閲覧

いいねボタンを押すと全てのデータにいいねがついてしまう

abrt29

総合スコア12

Vue.js

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

Vue CLI

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

0グッド

0クリップ

投稿2021/06/03 21:41

現在簡易的な飲食店予約アプリを下記順序で作成中です。
① バックエンド作成(Laravel)
② フロントエンド作成(Vue.cli)
③ 繋ぎ込み

*実装したいこと
フロントエンド側で店舗ごと、ユーザーごとにお気に入り登録できるようにしたい
例えばログインユーザーがAの店舗をお気に入りしたら、Aの店舗だけいいねボタンのハートマークの表示変更

*解決したいこと
1つの店舗のいいねボタンを押すと全部の店舗にもハートマークの表示が変更される

以下、該当コードとなります。
ご教授頂けますと幸甚です。

Vue.js

<template> <div class="home"> <div class="flex"> <div class="header left"> <commonHeader /> </div> <div class="search-container right"> <div class="flex"> <select name="shopsArea" id="" v-model="searchArea"> <option value="">エリアで検索</option> <option value="東京">東京</option> <option value="大阪">大阪</option> <option value="福岡">福岡</option> </select> <select name="shopsGenre" id="" v-model="searchGenre"> <option value="">ジャンルで検索</option> <option value="寿司">寿司</option> <option value="焼肉">焼肉</option> <option value="居酒屋">居酒屋</option> <option value="イタリアン">イタリアン</option> <option value="ラーメン">ラーメン</option> </select> <input type="text" v-model="searchWords" placeholder="店名で検索"> </div> </div> </div> <div class="shops" id="shop-flex"> <div class="shop" v-for="shop in filteredShops" :key="shop.id"> <img :src="shop.url"> <div class="shop-info"> <p class="shop-name">{{ shop.name }}</p> <div class="area-genre"> <span class="shop-area">#{{ shop.area }}</span> <span class="shop-genre">#{{ shop.genre }}</span> </div> <div class="flex"> <button @click="shopDetail(shop.id)">詳しく見る</button> <div class="LikesIcon" @click="toggleHeart()"> <i class="fa-heart LikesIcon-fa-heart" :class="{ heart: isActive , fas: isActive ,far: !isActive }"></i> </div> </div> </div> </div> </div> </div> </template> <script> import commonHeader from '../components/commonHeader'; export default { data() { return { searchArea: '', searchGenre: '', searchWords: '', isActive: false, shops: [ { id: 1, name: '仙人', area: '東京', genre: '寿司', url: 'https://coachtech-matter.s3-ap-northeast-1.amazonaws.com/image/sushi.jpg' }, { id: 2, name: '仙人', area: '大阪', genre: '焼肉', url: 'https://coachtech-matter.s3-ap-northeast-1.amazonaws.com/image/sushi.jpg' }, { id: 3, name: '仙人', area: '福岡', genre: 'イタリアン', url: 'https://coachtech-matter.s3-ap-northeast-1.amazonaws.com/image/sushi.jpg' }, { id: 4, name: '仙人', area: '東京', genre: '寿司', url: 'https://coachtech-matter.s3-ap-northeast-1.amazonaws.com/image/sushi.jpg' }, { id: 5, name: '仙人', area: '大阪', genre: '寿司', url: 'https://coachtech-matter.s3-ap-northeast-1.amazonaws.com/image/sushi.jpg' }, ], }; }, components: { commonHeader }, methods: { toggleHeart() { if (!this.isActive) { this.isActive = true; } else { this.isActive = false; } }, shopDetail(shop_id) { this.$router.push({path: '/shopdetail/'+ shop_id, params:{shop_id:shop_id}}); } }, computed: { filteredShops() { const shopsArray = []; for (const i in this.shops) { const shop = this.shops[i]; if (shop.area.indexOf(this.searchArea) !== -1 && shop.genre.indexOf(this.searchGenre) !== -1 && shop.name.indexOf(this.searchWords) !== -1) { shopsArray.push(shop); } } return shopsArray; } } }; </script>

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

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

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

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

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

FKM

2021/06/04 00:41

利用者ごとの評価用トランザクションはLaravel内で既に用意されているのでしょうか? Vueで制御されるのは店ごとの評価付与の制御だけなのでしょうか?
abrt29

2021/06/04 01:02

利用者ごとの評価用トランザクションはLaravel内で既に用意されているのでしょうか? ⇒まだしておりません。評価用のLikesテーブルは作成しております。繋ぎこみをする際にフロントエンド・バックエンドともに修正しながら記述するつもりです。 Vueで制御されるのは店ごとの評価付与の制御だけなのでしょうか? ⇒とりあえずはVueに仮データを記述し、上手く動作したら繋ぎこみに移るという風に考えております。
guest

回答1

0

これだとmethodsのtoggleHeartで、該当店舗を紐付けるものが何も示されていませんので、全店舗が対象となってしまいます。なので、選択した店舗のidを引っ張ってきて、候補の店舗の中から該当する店舗を取得するようにすればいいのではないでしょうか。

あと、isActiveがループで制御されている限り、紐付いた値は全部同じ値を返してしまうので、返す値はオブジェクトにして分類しないと駄目な気がします。

vue

1 //テンプレート 2 <div class="LikesIcon" @click="toggleHeart(shop.id)"> 3 <i class="fa-heart LikesIcon-fa-heart" :class="{ heart: isActive , fas: isActive ,far: !isActive }">いいね</i> 4   <input :value="act[shop.id]"><!-- テスト用 --> 5 //省略 6 isActive: false, 7   act: [], //ここに評価値を代入していく 8 shops: [ 9 //省略 10 methods:{ 11 toggleHeart(sel_id) { 12 let isActive = this.isActive 13 let act = this.act 14 this.filteredShops.filter(function(elem,idx){ 15 if(sel_id === elem.id){ 16 if (!isActive) { 17 act[sel_id] = true; 18 } else { 19 act[sel_id] = false; 20 } 21 } 22 }) 23 this.act = act 24 }, 25 26 }

ボタンとテキストボックスでひととおりの動作は検証できたのですが、アイコンでも希望通り動くかどうかは未検証です。

投稿2021/06/04 01:22

編集2021/06/04 02:05
FKM

総合スコア3647

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

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

abrt29

2021/06/04 01:43

ご回答ありがとうございます! 私も手元にパソコンが無いので夕方確認次第ご連絡致します!
abrt29

2021/06/04 12:48

すみません、同じように記述して確認したところ、 this.filteredShops.filter(function(elem, idx)) のidxが使用されていませんと怒られてしまいます。 また、idxを消して引数をelemだけにするとハートアイコンを押した際に色が切り替わりませんでした。 ご教授いただきますでしょうか。
FKM

2021/06/04 20:55

フラグはactに代入されているので、if判定でゴリ押しでもだめでしょうか?
abrt29

2021/06/04 21:40

まだ他にif文を作成しないといけないということでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問