LoginSignup
3
2

More than 1 year has passed since last update.

Nuxt Composition API でのpropsの使い方や型推論について

Last updated at Posted at 2021-11-19

目次

props(プロパティ)とは

vuejs公式 プロパティを用いた子コンポーネントへのデータの受け渡し
ではこう書かれています。

プロパティはコンポーネントに登録できるカスタム属性です。値がプロパティ属性に渡されると、そのコンポーネントインスタンスのプロパティになります。

要は親コンポーネントから子コンポーネントにデータを渡したい時propsを指定すると値を受け取ることができるということです。
その値を受け取る際にいろんな設定を行うことができます。

props(プロパティ)の設定

  • type
  • required
  • default
  • validation

type

プロパティの型のことです。

[String,Number,Boolean,Array,Object,Function,Promise]
などの型を指定することができます。

詳しくはvue.js公式 型の検査をご覧ください。

childComponent.vue
props:{
  type: {
    type: String,
  },
}

textはString (文字列)で指定していますが、
0のようなnumber型の値を子コンポーネントに渡すと下記のようなエラーが発生します。

[Vue warn]: Invalid prop: type check failed for prop "text". Expected String with value "0", got Number with value 0.

required

reuqiredは必須のプロパティか、を指定する設定になります。
true,falseで指定します。

childComponent.vue
props:{
  text: {
    type: String,
    required: true,
  },
}

textは必須のプロパティですが、親コンポーネントから渡されなかった場合下記のようなエラーが発生します。

[Vue warn]: Missing required prop: "text"

default

defaultは主にrequiredを設定していない際に利用します。

childComponent.vue
props:{
  text: {
    type: String,
    required: false,
    default: ''
  },
}

必須ではないので親コンポーネントから何も渡されないことがあります。
なのでデフォルトを指定すると親コンポーネントから何も渡されなかった場合デフォルトの値がpropsの値になります。

オブジェクトや配列についてはfactory関数で指定してあげる必要があるのですが、下記のqiitaの記事がわかりやすかったので紹介させていただきます
[Vue.js] なぜpropsのdefault値にObjectやArrayを指定する際にfactory関数にする必要があるのか

validator

validatorはpropsの値をもっと細かくバリデーションをかけたい場合に使います。

childComponent.vue
props:{
  length: {
    type: String,
    required: true,
    validator: (value: string) => {
        return ['long', 'regular', 'short'].includes(value)
    },
  },
}

validatorは返り値がfalseであった際、コンソールエラーが起きます。

[Vue warn]: Invalid prop: custom validator check failed for prop "length".

上記のコードは
引数のvalue(親コンポーネントで指定している値)が'long', 'regular', 'short'のどれかに一致しているか。を確認している内容になります。

なのでpropsのlengthstring型でありlongまたはregularまたはshortでない時にコンソールエラーが起きます。

propsの型推論

次はpropsの型推論についてです。

setup() 関数においては、props 引数に型をつける必要はありません。setup() 関数は props コンポーネントオプションから型を推論するからです。

引用元
Vue.js コンポジション API とともに使用する

childComponent.vue
import { defineComponent } from '@nuxtjs/composition-api'

export default defineComponent({
  props: {
    text: {
      type: String,
      required: true;
    },
    text2: {
      type: String,
      required: false,
      default: null,
    },
    num: {
      type: Number,
      required: true;
    },
    array: {
      type: Array,
      required: true;
    },
    obj: {
      type: Object,
      required: true;
    },   
  },
  setup(props) {
  },
})

// propsの型

// props: {
//    text: string
//    text2?: string | undefined
//    num: Number
//    array: unknown[]
//    obj: Record<string, any>
//

実際にpropsの型を調べた際、ちゃんと型推論がされていました。
requiredの値によってオプション(必須でない)が付くみたいですね。

しかし、配列やオブジェクトに関してはunknown[]Record<string, any>と細部までは定義されていませんでした。
こちらの問題を解決するためにはvueで用意されているPropTypeを利用する必要があります。

PropTypeについて

childComponent.vue
import { defineComponent, PropType } from '@nuxtjs/composition-api'

interface ArrayItem {
  name: string
}

interface Obj {
  title: string
}

export default defineComponent({
  props: {
    text: {
      type: String,
      required: true;
    },
    text2: {
      type: String,
      required: false,
      default: null,
    },
    num: {
      type: Number,
      required: true;
    },
    array: {
      type: Array as PropType<ArrayItem[]>,
      required: true;
    },
    obj: {
      type: Object as PropType<Obj>,
      required: true;
    },   
  },
  setup(props) {
  },
})

// propsの型

// props: {
//    text: string
//    text2?: string | undefined
//    num: Number
//    array: ArrayItem[]
//    obj: Obj
//

上記のコードのように型アサーションでPropTypeを指定すると
unknownやanyではない指定した型が割り当てられていました。

しかしPropTypeはバリデーションをかけているのではなく、型を上書きしているので
validatorやdefaultを設定する必要があります。

詳しくはこちらを下記の公式のページをご覧ください。
Props にアノテーションをつける

参照

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