3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vueのコンポーネントを学ぶ

Last updated at Posted at 2021-08-02

#はじめに
vue.jsをまた基礎から学びなおしているのですが、コンポーネントがなかなか理解した!と自信を持って言えないところです。
公式ドキュメントに沿って覚えたことを自分用解説つきで書いていきます。

#コンポーネントとは

コンポーネントシステムは Vue.js におけるもうひとつの重要な抽象概念です。「小さく、自己完結的で、(多くの場合)再利用可能なコンポーネント」を組み合わせることで、大規模アプリケーションを構築することが可能になります。アプリケーションのインターフェイスについて考えてみると、ほぼすべてのタイプのインターフェイスはコンポーネントツリーとして抽象化することができます

例えば、webページに共通のヘッダーフッターをすべてのページに出すとき、すべてのファイルにHTML分ちまちま書いたりしたくないですよね。このヘッダーフッターを再利用できるパーツ(再利用可能なコンポーネント)にしちゃおう!という感じです。

#簡単なコンポーネントを作って表示してみる
文字読んでてもよくわからないので一旦作ってみます。
サイトでよく見る、会社名と選択中のタイトル(見出し)を表示するやつをコンポーネント化してみます。
※コンポーネントの理解が主目的なので文言やデザインは超適当です。

componentsの直下にHeader.vueを作成します

Header.vue
<template>
  <div class="header">
    <h1>会社名</h1>
    <span>見出し</span>
  </div>
</template>

<script>
export default {
  name: 'Header',
}
</script>

<style scoped>
.header {
    background-color: #2fa16e;
    color: aliceblue;
}
</style>

この作ったコンポーネントを使用してみます。今回はIndex.vueというファイルで使用します

Index.vue
<template>
  <div id="app">
      <Header/> // 3
  </div>
</template>

<script>
import Header from './components/Header.vue' // 1

export default {
    name: "Index",
    components: {
        Header // 2
    },
}
</script>

1.Header.vueをimportします。importしたものをここではHeaderと呼ぶよ。という記述
2.Headerをコンポーネントとして扱ういますという記述
3.実際に使用
という感じです。

親:Index.vue
子:Header.vue
の関係になります。

実行してIndex.vueを表示した結果
キャプチャ.PNG

作成したHeader.vueコンポーネントが表示されました。

##使用するコンポーネント名を変えたいとき
先ほどの書き方ではHeader.vueHeaderという名前としてimportして使用しましたが、<>内での名称を変更することができます。

Index.vue
<template>
  <div id="app">
      <HeaderName/>
  </div>
</template>

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

export default {
    name: "Index",
    components: {
        "HeaderName": Header //ここを変更
    },
}
</script>

Headerをコンポーネントとして使用するときはHeaderNameという名前とするよ、という記述です。
それ以外の関数でHeader.vue使用する場合はそのままHeaderとなります。

#プロパティを受け取れるようにする【props】
先ほどの例では「会社名」「見出し」の文言が固定でしたが、文言をページごとに変えたい場合も多いと思います。
propsを使用することで親のスコープから子コンポーネントへとデータを渡せるようにできます。
試しに先ほどの例の「見出し」を変えられるようにしてみます。

##子コンポーネントの書き方

Header.vue
<template>
  <div class="header">
    <h1>会社名</h1>
    <span>{{ title }}</span>
  </div>
</template>

<script>
export default {
  name: 'Header',
  props: {
    title: String
  }
}
</script>

---以下略---

{{ title }}でtitleにセットされた値を受け取れるようにします。

では実際titleに何をいれるのか?
通常dataにtitleを定義しますが、今回titleに何が入るか決めるのは親でないといけません。そのため親からデータをもらえるようpropsを使用します。今回は文字列をもらうのでtitle: Stringとしています。

###補足1
以下のように書いても同じ動きになります。

Header.vue
<script>
export default {
  name: 'Header',
  props: {
    title: {
      type: String
    }
  }
}
</script>

###補足2
補足1のような書き方をすることで他の項目も定義できます。

Header.vue
<script>
export default {
  name: 'Header',
  props: {
    title: {
      type: String,
      default: 'デフォルト', //デフォルト値
      required: true //必須
    }
  }
}
</script>

##親コンポーネントの書き方

Index.vue
<template>
  <div id="app">
      <HeaderName title="見出し1"/>
      <HeaderName title="見出し2"/>
  </div>
</template>

<script>
import HeaderName from './components/Header.vue'

export default {
    name: "Index",
    components: {
        HeaderName
    },
}
</script>

title="見出し1"と渡す値を指定することができます。
わかりやすいように2つ並べてみました。
実行結果
キャプチャ.PNG

#プロパティに変数を渡す【props + v-bind】
propsで値を受け取れるようにしましたが、固定でなく変数を渡したい場合は以下のようにv-bindを使用します。
子コンポーネントはそのままで問題ありません。親を修正します。

Index.vue
<template>
  <div id="app">
      <HeaderName title="見出し1"/>
      <HeaderName title="見出し2"/>
      <HeaderName v-bind:title="title"/> --追加
  </div>
</template>

<script>
import HeaderName from './components/Header.vue'

export default {
    name: "Index",
    components: {
        HeaderName
    },
    data() {
        return {
            title: "見出し3",
        }
    },
}
</script>

v-bind:prop名="データ名"で変数を渡せます。
省略した場合は:prop名="データ名"となります。

実行結果
キャプチャ.PNG

##v-forを使用するとき
v-forでちょっと悩んだので書き方メモ。

###子コンポーネントの書き方

Header.vue
<template>
  <div>
    <li>{{ menu.name }}</li>
  </div>
</template>

<script>
export default {
  name: 'Header',
  props: {
    menu: Object
    }
}
</script>

###親コンポーネントの書き方

Index.vue
<template>
  <div id="app">
      <Header v-for="menu in menus"
              :key="menu.name"
              :menu="menu"/>
  </div>
</template>

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

export default {
    name: "Index",
    components: {
        Header
    },
    data() {
        return {
            menus: [
                {
                    name: "メニュー1"
                },
                {
                    name: "メニュー2"
                },
                {
                    name: "メニュー3"
                },
            ]
        }
    },
}
</script>

#さいごに
ドキュメントよみながら思い出しながら進めているので補足などあれば随時更新していきます。
また、なにか間違いやこうしたほうがいいよ等何かあればコメントいただけると嬉しいです。
最後まで読んでいただきありがとうございます!

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?