Aikの技術日記

技術的な進捗とか成果とかを細々と投稿するブログです。時々雑記も。

Nuxt.js使ってみた Part5~小ネタ:propsとdataの違い編~

はじめに

お久しぶり?です、筆者です。

前回は、Part2で実施したチュートリアル実践中に気になり深掘りしたこと3つ:

  • Vuexとは?
  • computedとmethodsの違い
  • propsとdataの違い

…のうち2番目の「computedとmethodsの違い」についてまとめてみました。
今回では、最後となる「propsとdataの違い」についてを見ていこうかなと。

今回もこちらの公式記事の内容そのまんまですが…。
なぜか公式記事って頭に入りにくいんですよね。
個人的にはこうして、一度ブログとしてまとめた方が頭に入りやすく…。

まぁ何が言いたいかというと、今回の記事の内容はほぼほぼ公式記事の内容となっているということです。
それでは行きましょう。

propsとdataの違い

チュートリアル実施時点では、propsとdataの違いについて筆者は…
「他コンポーネントからv-bindで値をバインドできるかできないか」くらいにしか理解してなかったので…。

ここいらでしっかりと理解しておいた方が後々苦労しないかなと思い、見てみることにしました。

まず、props(プロパティ)はコンポーネントから受け取るデータを定義するものです。
データは必ず親から子供に歯科渡すことができず、子供から親に渡すことはできません。(単方向データフロー)
次に、dataはVueインスタンスで利用するデータオブジェクトを定義するものです。

…うん、公式記事なり色々読んでもこれくらいしかわからず…。
「props data vue 違い」で調べても、上記くらいの内容で言い表せられる内容しかなかったのです。

不思議に思ってさらに調査していくと…どうも「プロパティとdataが示す前提となる範囲が異なるっぽい」という結論にいたり。

プロパティはあくまで「親子コンポーネント間の中でのお話」で、dataは「Vueインスタンスの中でのお話」で出てくるものでありそうです。

Vueインスタンスを定義した時に、各インスタンス内に存在するものがdata…。
Vueコンポーネント間でデータを受渡しする時に話題となるのがプロパティ…。
といった形でしょうか。

個人的には、異なるコンポーネント間でデータをやり取りする様なコードを書くことが多く感じるため…。
dataについてはあんまし意識することはないのかなと思いつつ。

いずれ意識することになるかもしれませんが…多分Vue.jsをある程度習熟しないと意識しないかもですね。

また、ここまで調査するのに面白い小ネタがいっぱい見つかりましたので…。
次から余談として、プロパティとdataに関する小ネタを記していこうかと。

余談: プロパティには型を定義しよう

プロパティには下記の様に、型を定義した方がいいとのこと。

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}

こうすることで、プロパティの各値の説明ができる他、型を間違えていたら警告もしてくれるとのこと。
プロパティはHTMLに直接記載して渡す形になるので、型の違い等になかなか気付きにくいなぁと思う次第ですが…。
警告を出してくれるなら、その心配もなくなりそうですね。

余談: プロパティを渡す時になぜ小文字で定義しないといけないのか

Vue.jsを書いている時にずっと思っていたこと…「プロパティを渡す時に、なぜ値をキャメルケースではなくケバブケースで書かないといけないのか」について。
例えば下記の様な感じで…:

<!-- HTML 内ではケバブケース -->
<blog-post post-title="hello!"></blog-post>
Vue.component('blog-post', {
  // JavaScript 内ではキャメルケース
  props: ['postTitle'],
  template: '<h3>{{ postTitle }}</h3>'
})

これについて、公式記事に言及があったので備忘録がわりにメモを。

HTMLの属性名は大文字小文字を区別せず、ブラウザは全ての大文字を小文字として解釈します。
つまりは、DOM(HTML)のテンプレート内においては、キャメルケースのプロパティはケバブケース(ハイフンで区切ったもの)を使用する必要があります。

参考: プロパティ — Vue.js

余談:v-bindを付けてプロパティを渡したときの挙動の差

プロパティは静的なものであればv-bindをつける必要はないですが、動的な値を渡す場合はv-bindを付与する必要があります。

<!-- 静的な値渡し -->
<blog-post title="My journey with Vue"></blog-post>
<!-- 動的な値渡し -->
<blog-post v-bind:likes="post.likes"></blog-post>

また、「文字列ではなくJavaScript式として値を渡したい!」なんて時も、v-bindを付与する必要があります。

<blog-post v-bind:is-published="false"></blog-post>

なお、何も値を指定しない場合は、trueを渡すのと等価となります。

<!-- trueが渡される -->
<blog-post is-published></blog-post>

余談: プロパティにオブジェクト丸ごと値渡し

プロパティには「そのプロパティに内包されるデータを丸ごと渡す」という機能があるそうで。
例えば下記の様な型を持つデータがあるとして:

post: {
  id: 1,
  title: 'My Journey with Vue'
}

上記のデータを子コンポーネントに渡す際は、下記の様に記述すると思いますが…。

<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

下記の様に記載しても、同じ様に動いてくれるそうです。ベンリ!!

<blog-post v-bind="post"></blog-post>

dataを定義するときの注意点

dataは下記の様に直接オブジェクトを内包するのではなく…:

data: {
  count: 0
}

下記の様に、関数にしないといけないそうです。

data: function () {
  return {
    count: 0
  }
}

こうしないと、dataの中身が同一コンポーネント間で共通のものになってしまいます
この辺りは公式記事をみるととても分かりやすいです: コンポーネントの基本 — Vue.js

おわりに

今回はチュートリアルで作成したコードのカスタマイズの中で気になった項目3つ:

  • Vuexとは?
  • computedとmethodsの違い
  • propsとdataの違い

…の内、最後となる「propsとdataの違い」について見ていきました。
ひとまず気になることはまとめ終わっちゃったので、今シリーズはいったん終わりになるかと。

もしまた気になることができたら、再度再開するかもしれません。
((まーその頃にはこのシリーズの存在を忘れてそうなので、別記事としてまとめちゃいそうですが

次はClean Architecture系の記事を書いていくかも…。
それでは|д゚*)