🟡

【Vue.js】コンポーネント(Component)について

に公開
2

この記事を読む前に

環境構築などが完了されてない方は以下を参照。
https://zenn.dev/code_journey_ys/articles/bbe3b67bed48e2

コンポーネントの考え方

コンポーネント階層を理解してブラウザに内容を表示させてみる


(完成イメージ)コンポーネント階層が3層(親-子-孫)のレイアウトを表示させる

今回実践するコンポーネント階層構造
今回は以下のディレクトリ構造で作成を行っていく(App.vue → Practice.vue → PracticeCom1.vueという流れでコンポーネントを読み込んでいく)
my-app/
├── src/
│   ├── App.vue           ← 全体の親(親)
│   ├── main.js           
│   ├── views/
│   │   └── Practice.vue  ← App.vueの子(子)
│   └── components/
│       └── PracticeCom1.vue ← Practice.vueの子(孫)
孫コンポーネント(PracticeCom1.vue)
src/components/PracticeCom1.vue(孫コンポーネント)
<template>
  <div class="practice-com1">
      <p>これは PracticeCom1.vue(孫コンポーネント)です!</p>
  </div>
</template>

<script>
export default {
 // ↑ この`export defaultを記述することでこのコンポーネントを外部ファイルでも使用可能となる
  name: 'PracticeCom1'
}
</script>
子コンポーネント(Practice.vue)
src/views/Practice.vue(子コンポーネント)
<template>
  <div class="practice">
    <h2>これは Practice.vue(子コンポーネント)です!</h2>
    <PracticeCom1 />
    //  ↑ 孫コンポーネント(PracticeCom1.vue)を挿入
  </div>
</template>

<script setup>
// ↑ <script setup> を使えば、コンポーネントの export default が不要となる。Vue が裏で自動的にエクスポートしてくれる。
import PracticeCom1 from '@/components/PracticeCom1.vue'
// ↑ import コンポーネント名 from 'ファイルパス'とすることで使用したいコンポーネントを読み込むことができる(@はsrc/を示す)。

</script>

親コンポーネント(src/App.vue)
src/App.vue(親コンポーネント)
<template>
  <div id="app">
    <h1>これは App.vue(親コンポーネント)です!</h1>
    <Practice />
       // ↑ 子コンポーネント(Practice.vue)を挿入
  </div>
</template>


<script setup>
// ↑ <script setup> を使えば、コンポーネントの export default が不要となる。Vue が裏で自動的にエクスポートしてくれる。
import Practice from '@/views/Practice.vue';
 // ↑ import コンポーネント名 from 'ファイルパス'とすることで使用したいコンポーネントを読み込むことができる(@はsrc/を示す)
       
</script>

その他ルーティング設定
src/router/index.js
// Vue Routerのインポート
import { createRouter, createWebHistory } from 'vue-router';

// ルートコンポーネントのインポート
import Pracrice from '../views/Pracrice.vue';

// ルート定義
const routes = [
  {
    path: '/practice',
    name: 'practice',
    component: Pracrice,
  }
];

// ルーターインスタンスの作成
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes,
});

// ルーターインスタンスをエクスポート
export default router;

コンポーネントにスタイルを適用する


(完成イメージ)先ほどの作成した子と孫のコンポーネントのみにスタイルを適用してみる

孫コンポーネント(PracticeCom.vue)
src/components/PracticeCom1.vue(孫コンポーネント)
<template>
  <div class="practice-com1">
      <p>これは PracticeCom1.vue(孫コンポーネント)です!</p>
  </div>
</template>

<script setup>

</script>

<style scoped>
// ↑ <style scoped> を使うと以下のような属性セレクタ付きのスタイルに変換してくれることで、CSSの適用先が限定される。
.practice-com1 {
  color: red;
  // 孫コンポーネントのみ赤字になる
}
</style>

子コンポーネント(Practice.vue)
src/views/Practice.vue(子コンポーネント)
<template>
  <div class="practice">
    <h2>これは Practice.vue(子コンポーネント)です!</h2>
    <PracticeCom1 />
  </div>
</template>

<script setup>
import PracticeCom1 from '@/components/PracticeCom1.vue'
</script>

<style scoped>
// ↑ <style scoped> を使うと以下のような属性セレクタ付きのスタイルに変換してくれることで、CSSの適用先が限定される。
.practice {
  color: blue;
    // 子コンポーネントのみ青字になる
}
</style>

<style scoped>の仕組み
<style scoped> を使うと以下のような属性セレクタ付きのスタイルに変換してくれることで、CSSの適用先が限定される。
h1[data-v-xxxxxxx] {
  color: red;
}


(検証ツールでの確認画面)

Options API(Vue2)Composition API(Vue3)

Composition APIの構文でコードを記述する


(完成イメージ)カウントボタンを押すと押した回数がカウントされる

孫コンポーネント(PracticeCom.vue)
src/components/PracticeCom1.vue(孫コンポーネント)
<template>
  <div class="practice-com1">
    <p>これは PracticeCom1.vue(孫コンポーネント)です!</p>
    <p>カウント: {{ count }}</p>
    <button @click="increment">カウントアップ</button>
    // ↑ クリックされるたびにincrement関数が呼び出される
  </div>
</template>

<script setup>
import { ref } from 'vue'
 // ↑ Vueのパッケージから ref関数を使いますという宣言。他の関数(watch,reactive)が使用したい場合は{ ref, watch }のように,でつないでインポートする。
const count = ref(0)
 // ↑ count の初期値は0というデータ定義を行っている。
const increment = () => {
  count.value++
}
 // ↑ increment関数による処理を記述【関数(メソッド)定義】ボタンアクションが走るごとにcountを1ずつ増やす処理。
</script>

<style scoped>
.practice-com1 {
  color: red;
}
</style>

他の関数一覧

リアクティブなデータ定義関連

関数 用途
ref() 単一の値をリアクティブにする(プリミティブ型に向く)
reactive() オブジェクト・配列をリアクティブにする(複数の値をまとめたいとき)
computed() 依存値から計算されるリアクティブ値を作る
readonly() 読み取り専用のリアクティブデータに変換する
shallowRef() 浅いリアクティブ(中のオブジェクトはリアクティブにならない)
toRef() reactive オブジェクトの1つのプロパティを ref に変換
toRefs() reactive オブジェクト全体を ref に展開する

リアクティブデータの監視

関数 用途
watch() リアクティブな値や関数を監視する
watchEffect() 自動で依存を収集して副作用を実行する

ライフサイクルフック

関数 用途
onMounted() コンポーネントがマウントされた後に実行される処理
onUnmounted() コンポーネントがアンマウントされる前に実行される処理
onUpdated() コンポーネントが更新された後
onBeforeMount() マウント前
onBeforeUnmount() アンマウント前
onBeforeUpdate() 更新前

テンプレートやDOM操作

関数 用途
defineProps() 親からの props を受け取る(<script setup> 専用)
defineEmits() 子コンポーネントがイベントを emit する(<script setup> 専用)
useSlots() <slot> の中身にアクセス
useAttrs() 継承された属性(class, style など)を取得

その他の便利な関数

関数 用途
provide() 子孫コンポーネントにデータを共有する
inject() 親や祖先コンポーネントからデータを受け取る
getCurrentInstance() 現在のコンポーネントインスタンスにアクセス(高度な用途)

Discussion

junerjuner

export default しなくても vue なら <script setup></script> 使えばいいのではないでしょうか……?

YusukeYusuke

コメントありがとうございます。
調べたみましたところ、ご指摘の通りでした。取り急ぎ修正いたします。
勉強になりました!本当にありがとうございます!