2
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?

Vue.js+Typescriptのpropsとemitの使い方

Last updated at Posted at 2021-12-16

1.@Propコンポーネント間のデータの受け渡し(親→子)

Vue.js+Typescriptde+vue-property-decoratorでpropsとemitを使うときの備忘録。

<Prop編>

親コンポーネントでは、子コンポーネントタグに子コンポーネントのプロパティ名をケバブケースで命名する。
(今回は、子コンポーネントのプロパティ名は「YourDinner」のため、親コンポーネントの属性名は「your-dinner」になる。)

親コンポーネント
<Component your-dinner="カレーライス"></Component>

                    ⬇︎   Props down

子コンポーネントでは、@Propデコレーターをつけたプロパティで受け取る。

子コンポーネント
@Prop({default:"なし"})
yourDinner!: string; //←上記の親コンポーネントで渡した「カレーライス」が入る。

親コンポーネントから渡ってくる値を受け取るyourDinner変数を定義。
値が渡ってこなかった場合は、default内の値がyourDinner変数に代入される。
デフォルト値を設定しない場合は以下のように()内に何も入れなくていい。

子コンポーネント
@Prop()

また、子コンポーネントでは今まで通り以下のように初期化はしない。

子コンポーネント
yourName="";

このようにしてしまうと、毎回yourNameに空文字が代入されて、親コンポーネントから値が渡されない。
しかし、空文字で初期化をしないと、トランスコンパイル時に「初期化されていない」というエラーが出てしまう。

「!」マークをつけることで、「初期化されていないが問題ない」ということをトランスコンパイラに伝えることができる。
また、TypeScriptでは初期値で変数の方を推論するが、初期化していないため、「:string」をつけて型指定をする。

<サンプルコード>

components/sample/CompPropsYourDinner.vue(子コンポーネント)
<template>
   <div class="sample">
     <div>あなたの夕食は{{yourDinner}}です</div>
   </div>
</template>

<script lang=ts>
import { Prop, Component, Vue } from "vue-property-decorator";
@Component
export default class CompPropsYourDinner extends Vue {
  @Prop({ default:"なし"})
  yourDinner!:string;
}

</script>

@Propデコレーターを使用するためには、"vue-property-decorater"からインポートする必要がある。

親コンポーネント
<template>
  <div class="sample">
    <CompPropsYourDinner your-dinner="カレーライス"></CompPropsYourDinner>
    <CompPropsYourDinner your-dinner="親子丼"></CompPropsYourDinner>
    <CompPropsYourDinner></CompPropsYourDinner>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import CompPropsYourDinner from "@/components/sample/ComPropsYourDinner.vue";
@Component({
  Component: {
    CompPropsYourDinner,
  },
})
export default class PropsParent extends Vue {}
</script>

3行目と4行目でそれぞれ、「カレーライス」と「親子丼」を子コンポーネントに渡している。
5行目ではyour-dinner属性が存在せず、値を渡していないのでデフォルト値の「なし」がyoueDinnerに入ることになる。

2.@Emit コンポーネント間のデータの受け渡し(子→親)

親コンポーネントで子コンポーネントで発生したイベントを拾う。
例)モーダル画面をクローズする場合

親コンポーネント
<LogoutModal v-on:close-modal="closeModal"></LogoutModal>

                       ⬆︎

子コンポーネントでは@Emitデコレーターをつけたメソッドでイベントを発生させる。

子コンポーネント
<button class="btn" vclick="closeModal">モーダルを閉じる</button>

@Emit()
  public closeModal): void {
    console.log("close-modalイベント発生");
  }

子コンポーネントのcloseModal()メソッドに@Emit()デコレーターを付けることで、close-modal()イベントが発生して、親コンポーネントに伝わる。
HTMLの特性で大文字、小文字を区別しないので、以下のようにかくことになる。
    メソッド名:closeModal(キャメルケース)←子コンポーネント
    イベント名:close-modal(ケバブケース)←親コンポーネント

<サンプルコード>

子コンポーネント
<template>
  <div class="sample">
    <button class="btn" v-on:click="closeModal">モーダルを閉じる</button>
  </div>
</template>

<script lang="ts">
import { Emit, Component, Vue } from "vue-property-decorator";
@Component
export default class CompModalEmit extends Vue {
  @Emit()
  closeModal(): void {
    console.log("close-modalイベント発生!");
  }
}
</script>

closeModal()メソッドについている@Emitデコレータは、イベントを発生させるデコレータで、同じメソッド名のイベントが発生して親コンポーネントに伝わる。
(このとき、子コンポーネントではキャメルケースのメソッド名だが、親コンポーネントではケバブケースに変換される)

親コンポーネント
<template>
  <div class="sample">
    <button @click="openModal">モーダルを開く</button>
    <CompModalEmit v-on:close-modal="closeModal" v-if="isModalOpen">
    </CompModalEmit>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import CompModalEmit from "../../components/sample/CompModalEmit.vue";
@Component({
  Components: {
    CompModalEmit,
  },
})
export default class EmitParent extends Vue {
  //モーダルの表示ステータス
  private isModalOpen = false;

  //モーダルを開く処理
  openModal(): void {
    this.isModalOpen = true;
  }

  //モーダルを閉じる処理
  closeModal(): void {
    this.isModalOpen = false;
  }
}
</script>

v-on:close-modal="closeModalで子コンポーネントで発生したclose-modal()イベントを拾って、親コンポーネントのcloseModal()メソッドを呼ぶ。

まとめ

データの受け渡しをするときは、
・親コンポーネントは、ケバブケース
・子コンポーネントは、キャメルケース
でメソッド名を書く。

親から子はPropで、子から親はEmit。

2
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
2
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?