l12a

白ウサギを追え

Vue.js で props に色々なデータを渡す実験

Vue.js を使った UI 開発で props からデータを受け取るときのデータチェック機構を知るために色々渡してみました。
擬似コード混ざりますので雰囲気でお願いします。)

コンポーネント上での props 定義

このようなコンポーネントを用意しました。 xy 二つの props を受け取り、一方は required: false で optional になっています。

{
  name: 'FooComponent',
  props: {
    x: {
      type: String,
      required: true,
    },
    y: {
      type: String,
      required: false,
      default: 'default string y',
    },
  }
}

x (required props) に色々なデータを渡す

required: true の props はイメージと違うことはなく、そうなるだろうなという感じでした。

null

<foo-component :x="null" :y="'prop value y'">

コンソールでは warn が表示されます。

[Vue warn]: Invalid prop: type check failed for prop "x". Expected String with value "null", got Null

プロパティは null が返ります

console.log(this.x) // null

undefined

<foo-component :x="undefined" :y="'prop value y'">

コンソールでは warn が表示されます。

[Vue warn]: Invalid prop: type check failed for prop "x". Expected String with value "undefined", got Undefined 

プロパティは undefined が返ります

console.log(this.x) // undefined

false

<foo-component :x="false" :y="'prop value y'">

コンソールでは warn が表示されます。

[Vue warn]: Invalid prop: type check failed for prop "x". Expected String, got Boolean with value false.

プロパティは false が返ります

console.log(this.x) // false

型違いのデータ

<foo-component :x="42" :y="'prop value y'">

コンソールでは warn が表示されます。

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

プロパティは渡されたデータ 42 が返ります

console.log(this.x) // 42

データを渡さない場合

<foo-component :y="'prop value y'">

コンソールでは warn が表示されます。

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

プロパティは undefined が返ります

console.log(this.x) // undefined

y (optional props) に色々なデータを渡す

required: true の props と同様となるところは省略し、挙動の違うところを主に記載します。

null

<foo-component :x="'prop value x'" :y="null">

コンソールでは warn が表示されず、プロパティは null が返ります

console.log(this.y) // null

undefined

<foo-component :x="'prop value x'" :y="undefined">

コンソールでは warn が表示されず、プロパティは undefined が返ります

console.log(this.y) // undefined

false

required: true の props と同様です。

型違いのデータ

required: true の props と同様です。

データを渡さない場合

<foo-component :x="'prop value x'">

コンソールでは warn が表示されす、プロパティは冒頭で定義したデフォルトの値が返ります

console.log(this.y) // default string y

僕の場合は eslint-plugin-vuevue/require-default-prop ルールを有効にしている場合が多いのでデフォルトの値を指定していますが、これをしなければ required: true の props と同様に undefined が返ります。
また逆に required: true の props でもデフォルト値を指定していれば、その値が返ります。

終わりに

  • props の type 指定と required 指定は warn を出すだけなのでアプリケーションがエラーで止まるわけではありません。
    • 型が違うことによってできない操作( String 型にしかない関数を呼び出そうとしたが、渡ってきたデータが Number 型だった時など)をしようとすればエラーを起こしてしまいます。
  • props の required 指定はデータが渡されない時だけでなく、 nullundefined の時の warn が出るかどうかが違います。
  • props の default がセットされるのは、データが渡されなかった時だけです。

    ハマりそうなポイント

    前述の特性により、条件によってはコーディングミスに気がつきにくい可能性があります。 例えば以下のようなコンポーネントがあり、

<template>
  <input type="hidden" name="bar" :value="barValue">
</template>

<script>
export default {
  name: "BarComponent",
  props: {
    barValue: {
      type: String,
      required: false,
      default: "default value bar"
    }
  }
};
</script>
<bar-component :bar-value="null" />

呼び出す際に props に渡すデータが nullundefined になる可能性があるとすると、 * required: false なので warn が出ない * props を渡してはいるので、 default が使われない * 受けた props を input 要素にバインドしているだけなので、エラーが起きない といった感じの挙動になり、バグを仕込むことになるかもしれません。 よく理解して使っていきたいと思います。