見出し画像

はじめてのコンポーネント [Vue.js]

この記事はVue.js 初学者が、初めてVue を用いてコンポーネントを利用した経験をまとめたものです。初歩的なことがまとめてあります。

以下のサンプルコードでは、Vue.js にTypeScript のサポートを導入しており、かつVue.js ver2.0とver3.0 の書き方が混同しているので、少しダーティなコードになっているかもしれません。
ご了承ください m(_ _)m
(また動作確認していないので動かない部分があるかもしれません)

コンポーネントの定義

defineComponent: コンポーネント定義

TypeScriptを用いたコンポーネント定義についてVue.js公式では、defoneComponentを用いて、以下のように紹介されています。

単一ファイルコンポーネント を使っている場合、これは一般的に次のように書かれます

Vue.js公式
<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
   //   setup() {
   //      const count = value(0)
   //      const plusOne = computed(() => count.value + 1)
   //      const increment = () => { count.value++ }
   //      return {
   //          count,
   //          plusOne,
   //          increment
   //     };
   //  }
})
</script>

上記defineComponent と以下のsetup() を用いることで、コンポーネントの定義は大体おっけいです。

setup: プログラムの定義

上記サンプルコードで用いている、setup関数はVue3.0から導入されました。dataやcomputed, methodsといったそれぞれのプログラムを個別で定義することなく、同列で定義することが可能になっています。

// ver3の書き方
export default {
  setup() {
    const count = value(0)
    const plusOne = computed(() => count.value + 1)
    const increment = () => { count.value++ }
  }
}

// ver2の書き方
export default {
  data () {
    return {
      count:0
    }
  },
  computed: {
    plusOne () {
      return this.count + 1
    }
  },
  methods: {
    increment () {
      return this.count++
    }
  }
}

子コンポーネントの呼び出し

ここではコンポーネントから、コンポーネントを呼び出す、いわゆる「ローカル登録」の方法を紹介します。
どのファイルからでもコンポーネントを利用できる「グローバル登録」については、ここでは割愛します。

Vue.js が提供する components プロパティを用いて、利用したいコンポーネントを定義します。ただそのために、利用したいコンポーネントを import して読み込んでおく必要があります。

<template>
    <div>
        <child-component></child-component>
    </div>
</template>

// ローカル登録 with TypeScript
<script lang="ts">
import ChildComponet from '~/components/ChildComponet.vue'

export default defineComponent({
    components: {
        ChildComponet,
        // ChildComponet: ChildComponet の省略記法
    },
    :
})
</script>

コンポーネント間のデータの引き渡し

props: 親から子へ

親から子へのデータの引き渡しには props を用いる。

<template>
    // v-bind:変数名="渡したい値"
    // 上記の省略形 :変数名="渡したい値"
    <child-component :number="number"></child-component>
</template>

<script lang="ts">
import { defineComponent, reactive, computed } from "vue";
import ChildComponent from '~/components/ChildComponent.vue'

export default defineComponent({
    components: {
        ChildComponet,
    },
    data() {
        return {
            number: 3
        }
    },
    :
})
<script>
<template>
    // 引き受けた値を用いることが可能
    {{ number }}
</template>

// propsで値を受け取る
// typeやrequiredでvalidationを設定する
<script lang="ts">
export default {
    props: {
        number: {
            type: Number,
            required: true
        },
        :
    },
    :
}
<script>

emit: 子から親へ

子から親へのデータの引き渡し・メソッドの発火には emit を用いる。
ただemitはpropsのように素直にデータを引き渡すためのものではなく、子コンポーネント側から親コンポーネントのメソッドを叩けるようにするもの。
処理の流れとしては、以下の通り。

  1. 子コンポーネントでchildMethodが発火

  2. childMethod内でemitする(引数も渡す)

  3. 親コンポーネント内でchildMethodに紐づいたparentMethod が発火する

  4. parentMethod 内で、emitの際に渡された値を受け取り利用する

<template>
    <child-component
        :number="number"
         @childMethod="parentMethod"
    ></child-component>
    // @childMethod="parentMethod" の部分で親と子のコンポーネントのメソッドを紐付ける
</template>

<script lang="ts">
import { defineComponent, reactive, computed } from "vue";
import ChildComponent from '~/components/ChildComponent.vue'

export default defineComponent({
    components: {
        ChildComponet,
    },
    data() {
        return {
            number: 3
        }
    },
    setup(props, context) {
        const parentMethod = (number): void => {
            // 引数numberとして、子コンポーネントでemitされた際の値を受け取る (props.number + 1 のこと)
        }
    }
    return {
      childMethod
    }
    :
})
<script>
<template>
    <button @click.stop.prevent="childMethod()">
    </button>
</template>

// 以下は最小限の要素
<script lang="ts">
import { defineComponent, computed } from "vue";

export default defineComponent({
    props: {
        number: {
          type: Number,
          required: true
        }
    },
    setup(props, context) {
        // emitすることで、親要素に対してpagechangeを発火させることができる。
        const childMethod = (): void => {
            context.emit('childMethod', props.number + 1)
        }
    }
    return {
      childMethod
    }
})
</script>

おわりに

今回は恐ら基礎中の基礎的なことを記述させて頂きました。
少しVueのプロジェクトから離れるので、コードを中心に備忘録として記述しました。

動作できるか確認できていないので、正確さは低いかもしれません、、
自分の中でindexを作成しておくこと、ダイジ。

参考

この記事が気に入ったらサポートをしてみませんか?