【Nuxt.js】Components番外編: 親子間のやりとりを$emit, props, Vuexで見てみよう

# 前置き

コンポーネント間のやりとりについて、
やりたいことがある時に
パターンがいくつかあるよという例です🍒
近々Vuexに関する記事を投稿していたので
そのパターンも含めて書いてみました✍️
それぞれどんな時に使うかも
目次ごとに記載しています🌟
**・emit, $event
・propsをfunc
・ Vuex**

propsでfuncすることは
あまりないのですが…！
初めから誰もが見やすい
完璧なコードを目指すのではなく、
動かすだけならこんな方法もある！
と知ることは大事だと思います🎈🧸

🌟それぞれ基礎編の記事はこちら
emit基礎編
https://note.com/aliz/n/nd6e771724cd7
props基礎編
https://note.com/aliz/n/n99144d4556b9
vuex基礎編
https://note.com/aliz/n/n497914c981c8

# やりたいこと
![name.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/0428f12a-62d3-ce8d-676e-08f5c3865b4f.gif)

buttonで名前を変えるだけです笑
とにかくシンプルにわかりやすく！
がモットーです😄
表示はこちらです。
・親ではname
・子ではmyName

```bash:file
components/
--| Name.vue

pages/
--| index.vue

store/
--| index.js
```

# パターン1: $emit, $event

【どんな時に使う？】
今回のように構造がシンプルな時⭕️
というか基本はコレです！✨
親で渡しているpropsの値を変えます。
これができればモーダルウィンドウも簡単！
https://note.com/aliz/n/n2f0bc857defb

❓では子で値を変えると
　動作はしますがエラーになりますね。
![error.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/003679c5-3774-5590-bbf1-ab37acc0bda9.gif)

```Name.vue
<template>
 <div class="button">
   <p>myName: {{ myName }}</p>
   <button @click="changeName">
     reset
   </button>
 </div>
</template>

<script>
export default {
 props: {
   myName: {
     type: String,
     required: false
   },
 },
 methods: {
   changeName() {
     this.myName = "Max"
     this.$emit('nameSwitch', this.myName)
　　　// または1行にまとめて
     this.$emit('nameSwitch', 'Max')
   }
 },
}
</script>
```

【index.vue】
@nameSwitch="name = $event"
親にあるdataのname: 'Bob'を
イベントで操作します🌟
@nameSwitch="name"にすると
通常methodsのname()になるけど
dataのnameをイベントで渡すことにより
子のmethods, resetNameを使用します！

$emitカスタムイベント
https://jp.vuejs.org/v2/guide/components-custom-events.html

```index.vue
<template>
 <div class="page">
   <p>name: {{ name }}</p>
   <Name
     :myName="name"
     @nameSwitch="name = $event"
   />
 </div>
</template>

<script>
import Name from '~/components/Name.vue'

export default {
 components: {
   Name
 },
 data () {
   return {
     name: "Bob"
   }
 },
}
</script>
```

親にmethods追加して
名前を戻してみましょう。
ちゃんと戻りますね🌟
![error2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/a32ccfed-9c04-bc16-c009-ae9596c5442d.gif)

```index.vue
<template>
 <div class="page">
   <p>name: {{ name }}</p>
   <Name
     :myName="name"
     @nameSwitch="name = $event"
   />
   <button @click="resetName">
     reset
   </button>
 </div>
</template>

<script>
import Name from '~/components/Name.vue'

export default {
 components: {
   Name
 },
 data () {
   return {
     name: "Bob"
   }
 },
 methods: {
   resetName () {
     this.name = "Bob"
   },
 },
}
</script>
```

エラー解消は
子で値を変えなければOKです！
基礎編をご覧ください🌟👀

# パターン2: propsをfunc

【どんな時に使う？】
あんまり使いません。
前置きに書いたように
動かす手段の1つとしてご紹介。

【特徴】
コードは単純で分かりやすいです😀
ただこれをやるなら
$emitやvueの方が良いですね⭕️
子と親でのやりとりを
理解するのには最もシンプルで
良いかもしれません💡

こちらが参考になります！
https://kuroeveryday.blogspot.com/2017/09/vuejs-callback-vs-emit-events.html

```Name.vue
<template>
 <div class="button">
   <p>myName: {{ myName }}</p>
   <button @click="resetFn">
     resetFn
   </button>
 </div>
</template>

<script>
export default {
 props: {
   myName: {
     type: String,
     required: false
   },
   resetFn: {
     type: Function
   },
 },
}
</script>
```

```index.vue
<template>
 <div class="page">
   <p>name: {{ name }}</p>
   <Name
     :myName="name"
　　　:resetFn = "resetName"
   />
 </div>
</template>

<script>
import Name from '~/components/Name.vue'

export default {
 components: {
   Name
 },
 data () {
   return {
     name: "Bob"
   }
 },
 methods: {
   resetName () {
     this.name = "Max"
   },
 },
}
</script>
```

# パターン3: vuex

【どんな時に使う？】
ネストが深すぎてpropsがどうなってるか
分かりにくい！！って時に使います。
あとはサーバーとの通信が基本なので
今回のシンプルかつ通信不要な際は使いません。

ただ導入が容易ではなく
気軽にオススメはしません🙅‍♂️💥
本当に必要な時には⭕️

【特徴】
一見、コードもファイルも増えて
ごちゃついてそうな印象ですが☁️
何がどこにあって、が超絶見やすいですね✨👀

```Name.vue
<template>
 <div class="button">
   <p>myName: {{ myName }}</p>
 </div>
</template>

<script>
export default {
 props: {
   myName: {
     type: String,
     required: false
   },
 },
}
</script>
```


```index.vue
<template>
 <div class="page">
   <p>name: {{ name }}</p>
   <Name
     :myName="name"
     @nameWasReset="name = $event"
   />
   <button @click="$store.commit('changeName')">
     change
   </button>
 </div>
</template>

<script>
import Name from '~/components/Name.vue'

export default {
 components: {
   Name
 },
 computed: {
   name () {
     return this.$store.getters.name
   },
 },
}
</script>
```

```index.js
export const state = () => ({
 name: "Max",
})

export const getters = {
 name(state) {
   return state.name
 },
}

export const mutations = {
 changeName(state) {
   state.name = "Bob"
 },
}
```


**記事が公開したときにわかる様に、
note・Twitterフォローをお願いします😀**
https://twitter.com/aLizlab