【Vue.js入門】そこそこ分かりやすいv-forの「全部に反映」「個別に反映」

https://prosuku.com/

というVue✖️Firebaseで作ったサイトを公開してみたのですが、

その時に得たものをアウトプットしていきたいと思います。

https://qiita.com/prosuku/items/eebcefdbc34f45f8c62c

#詰まったところ

v-forで回した個別のアイテムに対して反映させたいものができた。

例えば、いいねを押したらそのポストにだけ数値が＋１されるようなときです。


#結論
v-forで回して子コンポーネントでmethodsの処理を書けば良い

```
<div v-for"item in items" :key="item.id">
  <child :item="item"/>
</div>
```
childコンポーネントで処理を書けば、個別のアイテムに対してだけ反映されます。

#そこそこ分かりやすい解説
##例１　全部に反映させるパターン
```Home.vue
<template>
  <div class="m-auto d-flex">
    <div v-for="item of 5" class="yokosen">
      <p>{{item}}</p>
      <p>counts: {{ counts }}</p>
      <v-btn @click="addCounts">count+</v-btn>
      <HomeChild />
    </div>
  </div>
</template>

<script>
import HomeChild from '@/components/HomeChild';

export default {
  components: {
    HomeChild,
  },
  data(){
    return{
      counts: 0,
    }
  },
  methods: {
    addCounts(){
      this.counts++
    }
  }
};
</script>
<style>
  .yokosen {
    border-right: solid 1px black;
  }
</style>
```
<img width="495" alt="スクリーンショット 2019-10-06 11.02.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507050/2594be77-f7ab-6de7-b962-e865e4670107.png">

この場合、どのカウントを押しても全部に反映されちゃいます。
これはこれで使えますね。
（現状、HomeChildの中身は空です。）

##個別に反映させるパターン
```Home.vue
<template>
  <div class="m-auto d-flex">
    <div v-for="item of 5" class="yokosen">
      <HomeChild :item="item"/>
    </div>
  </div>
</template>

<script>
import HomeChild from '@/components/HomeChild';

export default {
  components: {
    HomeChild,
  },
};
</script>
<style>
  .yokosen {
    border-right: solid 1px black;
  }
</style>
```
```HomeChild.vue
<template>
  <div>
    <p>{{item}}</p>
    <p>counts: {{ counts }}</p>
    <v-btn @click="addCounts">count+</v-btn>
  </div>
</template>
<script>
 export default {
  props: {
      item: '',
  },
  data(){
    return{
      counts: 0,
    }
  },
  methods: {
    addCounts(){
      this.counts++
    }
  }
}
</script>
```

<img width="495" alt="スクリーンショット 2019-10-06 11.11.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507050/7a56640d-492b-aa8c-5140-dc9d37ef0686.png">

個別に反映できました。

v-forで回したitemは、v-bindを使って

```
<HomeChild :item="item"/>
```
と定義をすれば子コンポーネントでも使えるのですが、
その際は、childコンポーネントにpropsで定義しないと使えません。

```
  props: {
      item: '',
  },
```
ややこしいぜ。

##全体に反映させるやつと個別に反映させるやつ同時に欲しい
子→親→子とデータを持っていくのは大変なので、Vuex使えば良いです。

```HomeChild.vue
<template>
    <div>
      <p>{{item}}</p>
      <p>counts: {{ counts }}</p>
      <v-btn @click="addCounts">count+</v-btn>
      <p class="mt-5">allCounts: {{$store.state.allCounts}} </p>
      <v-btn @click="addAllCounts">allCounts+</v-btn>
    </div>
</template>
<script>
import {mapActions} from 'vuex'

export default {
  props: {
      item: '',
  },
  data(){
    return{
      counts: 0,
    }
  },
  methods: {
    addCounts(){
      this.counts++
    },
    ...mapActions(['addAllCounts'])
  }
}
</script>

```

```store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    allCounts: 0,
  },
  mutations: {
    addAllCounts(state){
      state.allCounts++
    }
  },
  actions: {
    addAllCounts({ commit }){
      commit('addAllCounts')
    }
  }
})
```

<img width="662" alt="スクリーンショット 2019-10-06 11.23.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507050/b1c78181-14dd-571f-0126-9e96be8d8133.png">

以上です！

#おまけ(デバッグ方法）
```HomeChild.vue
 <p>{{$data}}</p>
 <p>{{$store.state}}</p>     
```
<img width="662" alt="スクリーンショット 2019-10-06 11.35.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507050/4c97d0ee-6dd8-1a7f-81be-d118c85eb166.png">

データが全てみられるので、すごく便利です。