Vueコンポーネント間まとめ1（値渡し）


#目的
Vueのコンポーネント間で利用するあれこれを知識としてまとめておく

#環境
Windows10
node v12.2.0
@vue/cli 4.1.1
vue v2.6.10

#コンポーネント基本(定義と利用)
コンポーネント側

```src/components/buttonCounter.vue
<template>
  <button v-on:click="count++">You clicked me {{ count }} times.</button>
</template>

<script>
export default {
  data: function() {
    return {
      count: 0
    };
  }
};
</script>
```

呼び出し側

```src/App.vue
<template>
  <div id="app">
    <buttonCounter/>
  </div>
</template>

<script>
import buttonCounter from './components/buttonCounter.vue'

export default {
  components: {
    buttonCounter
  }
}
</script>
```

![vue1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/843152ac-5595-61e5-42cc-fe421d572fc5.png)
#データの受け渡し
##静的データ

```src/components/blogPost.vue
<template>
  <h3>{{ title }}</h3>
</template>

<script>
export default {
  props: ["title"]
};
</script>
```

```src/App.vue
<template>
  <div id="app">
    <blogPost title="My journey with Vue"></blogPost>
    <blogPost title="Blogging with Vue"></blogPost>
    <blogPost title="Why Vue is so fun"></blogPost>
  </div>
</template>

<script>
import blogPost from "./components/blogPost.vue";

export default {
  components: {
    blogPost
  }
};
</script>
```
![vue2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/589dc079-1b53-df0b-c17e-f9aca0d52bb7.png)


##変数を利用
- v-bindを利用して値渡しを行う
- 結果は上記と同じ

```src/App.vue
<template>
  <div id="app">
    <blog-post
      v-for="post in posts"
      v-bind:key="post.id"
      v-bind:title="post.title"
    ></blog-post>
  </div>
</template>

<script>
import blogPost from "./components/blogPost.vue";

export default {
  components: {
    blogPost
  },
  data: function() {
    return {
      posts: [
        { id: 1, title: "My journey with Vue" },
        { id: 2, title: "Blogging with Vue" },
        { id: 3, title: "Why Vue is so fun" }
      ]
    };
  }
};
</script>
```

### 複数bindする必要がある場合

```src/components/blogPost.vue
<template>
  <div class="blog-post">
    <h3>{{ post.title }}</h3>
    <div v-html="post.content"></div>
    <div>{{ post.publishedAt }}</div>
    <div>{{ post.comments }}</div>
  </div>
</template>

<script>
export default {
  props: ["post"]
};
</script>
```

```src/App.vue
<template>
  <div id="app">
    <blog-post
      v-for="post in posts"
      v-bind:key="post.id"
      v-bind:post="post"
    ></blog-post>
  </div>
</template>

<script>
import blogPost from "./components/blogPost.vue";

export default {
  components: {
    blogPost
  },
  data: function() {
    return {
      posts: [
        {
          id: 1,
          title: "My journey with Vue",
          content: "content1",
          publishedAt: "publishedAt1",
          comments: "comments1"
        },
        {
          id: 2,
          title: "Blogging with Vue",
          content: "content2",
          publishedAt: "publishedAt2",
          comments: "comments2"
        },
        {
          id: 3,
          title: "Why Vue is so fun",
          content: "content3",
          publishedAt: "publishedAt3",
          comments: "comments3"
        }
      ]
    };
  }
};
</script>
```

# ここまで理解した上で読んで知っておくべきこと

[Vue公式Guide#プロパティ](https://jp.vuejs.org/v2/guide/components-props.html)

*v-bindについてはVueを少し触っただけでも理解できると思いますが、上記リンクの内容をすべて理解している人は少ないのではないでしょうか*

個人的要点

- プロパティの形式 (キャメルケース vs ケバブケース)
    - JavaScript 内ではキャメルケース、HTML 内ではケバブケース 
- 単方向のデータフロー
    - 親⇒子の単方向のバインディングのみ
    - **例外：オブジェクトと配列は参照渡しのため、子コンポーネント内で配列やオブジェクトを変更すると、親の状態へと影響します。**
- プロパティのバリデーション
    - type : String、Number、Boolean、Array、Object、Date、Function、Symbol
    - type はカスタムコンストラクタ関数でもある
- プロパティでない属性
    - プロパティでない属性は、属性としてコンポーネントに受け渡されるが、対応するプロパティは定義されない