BETA

UdemyのVue JS講座を受講した際のメモ その2

投稿日:2020-04-27
最終更新:2020-04-27

講座名

超Vue JS 2 完全パック - もう他の教材は買わなくてOK!

v-ifディレクティブについて

  • v-if="真偽値"で表示の有無を切り替えることができるディレクティブ。
  • v-else-ifや、v-elseと組み合わせることで、複雑に表示を切り替えることもできる。
  • v-else-ifv-elsev-ifの直下にないといけない。
  • 例えば、ある値に応じてまとめて表示を切り替えたい場合などはtemplateタグが有効(templateタグはhtml5の機能)
  • templateタグは、Vueテンプレートをhtmlに変換した際に展開されない。
  • divタグなどでもグルーピングは可能だが、htmlに展開されてしまう。

See the Pen v-if by popy1017 (@popy1017) on CodePen.

v-showディレクティブについて

  • v-show="真偽値"で表示の有無を切り替えることができるディレクティブ
  • v-ifと同じような動作をさせることができる
  • v-ifとの違いは、v-if="false"がタグごと削除するのに対して、v-show="false"はそのタグを見えなくする(style="display: none;"を付与する)といった点である。
  • それがいったいなんなのかというと、v-showは真偽値にかかわらずタグを描画してその後styleを適用するため、初期描画コストが高い反面、切り替えはstyleを切り替えるだけなので、切替コストは低い。
  • 一方で、v-ifは、flaseの場合タグ自体が描画されないため、初期描画コストは低くなるが、切替時にはタグごと削除・生成が行われるため、切替コストが高い。
  • まとめると、切替が頻繁に行われる部分はv-showを、切替があまり行われない部分はv-ifを使うと良い。
  • また、注意点としては、templateタグではv-showは正常に動作しない(表示されたままになる)ことがある。これは、templateはVueテンプレートがhtmlに変換されるときに消えるという性質を持っており、v-showは指定されたタグに対してdisplay: noneというスタイルを適用するため、templateタグにv-showを書いてもhtml変換時にはstyleが適用されたtemplateタグが消えてしまうからである。

v-forディレクティブについて

  • 配列の中身を順番に表示させたいときなどに使用する。
  • v-for="変数名 in 配列名"とすると、指定した配列に格納されている要素に指定した変数名でアクセスすることができる。
  • 第2引数を指定すると、インデックスを取得することができる。(v-for="(value, index) in array")
  • v-for="変数名 in オブジェクト"とすることで、オブジェクトのバリューをとってくることもできる。※オブジェクトの中の順番は保証されていないので注意。
  • 反復対象にオブジェクトを指定する場合、第二引数はkeyの値、第三引数がindexの値が入る。(v-for="(value, key, index) in object")
  • v-forに対しても、templateタグを用いたグルーピングが使える。
  • また、v-for="n in 10"のように数字で使うこともできる。
  • inをofに置き換えることができる。

See the Pen v-for by popy1017 (@popy1017) on CodePen.

key属性について

バグの温床になりかねないので、
v-forディレクティブを使う時は、必ずkey属性を使う。

  • v-forの問題点は、「要素の移動を最小限に抑えるアルゴリズムを使用し、同じタイプの要素を再利用する」点である。
  • つまり、v-forを使っているとき、要素数が変わる前と変わった後の要素の差分をみて、同じものは再利用して、異なっている部分は再レンダリングする、ということである。
  • 例えば、v-forを使ってレンダリングされた結果が以下のようなフォームにおいて、それぞれの入力フォームにそれぞれの上に書いてある果物の名前を入力した状態で「先頭を削除」ボタンを押すと、削除後のような状態になる。
  • html上で見ると問題ないように見えるが、Viewを確認すると、bananaのところのフォームにはappleが、orangeのところのフォームにはbanabaが入力された状態になる。
  • これは、削除前と削除後のhtmlにおいて、pタグは果物の名前が入っているので差分があり、再描画が行われるのに対して、inputタグの部分には差分がないため再描画が行われないことが原因である。
<!-- 削除前 -->  
<div id="app">  
    <div>  
        <p>apple</p>   
        <input type="text">  
    </div>  
    <div>  
        <p>banana</p>  
        <input type="text">  
    </div>  
    <div>  
        <p>orange</p>  
        <input type="text"></div>  
    <button>先頭を削除</button>  
</div>  
<!-- 削除後 -->  
<div id="app">  
    <div>  
        <p>banana</p>  
        <input type="text">  
    </div>  
    <div>  
        <p>orange</p>  
        <input type="text"></div>  
    <button>先頭を削除</button>  
</div>  
  • これに対処するためには、key属性を使う。
  • 反復対象のそれぞれの要素(今回だとdivタグ)にkey属性を指定することで、div全体に差分があったと判定されるようになり、上記のような結果となることを防げる。
  • 注意点としては、templateでkeyは使えない、keyにindexは指定しない(要素数が変わったら順番が変わってしまうため)点がある。

See the Pen v-for-problem by popy1017 (@popy1017) on CodePen.

Vueインスタンスについて

Vueインスタンスは複数定義することができる。

  • ただし、それぞれが完全に独立である場合のみ使用を推奨。(独立でない場合、ロジックが非常に複雑になってしまう。)

Vueインスタンスに外側からアクセスする

  • Vueインスタンスの外側からVueインスタンスのdataにアクセスしたい場合は、Vueインスタンスを作る際に変数に代入することでdataプロパティにアクセスすることができる。let vm = new Vue({});
  • Vueインスタンスの外側から、プロパティを追加することはできるが、リアクティブにならない。(値を変更しても再描画されない)
  • なぜかと言うと、Vueインスタンスを宣言する際にdataプロパティにあるプロパティに対しては、自動的にgetterとsetterが追加され、後から追加したプロパティにはそれらがないからである。
  • その様子は、Vueインスタンスをconsole.logなどで出力してみると確認できる。

Vueインスタンスのプロパティについて

  • dataプロパティに指定したオブジェクト自体を取得したい際は、Vueインスタンスを格納した変数名.$dataで取得できる。※dataではなく$dataである点に注意。
  • Vueインスタンスのプロパティの中で、Vueが定義しているものには$が頭についている。($el,$dataなど)
  • インスタンスの内側からアクセスしたい場合は、this.$dataでアクセスできる。
  • {Vueインスタンスの変数名}.$mount("{要素の名前}");で、後からel: "要素名"で指定している部分の代わり要素と関連づけることができる。

templateプロパティと、renderプロパティについて

  • Vueではテンプレートの書き方に3通りの方法がある。
  • 1つは、htmlに直接書くやり方。
  • 2つ目は、Vueインスタンスのtemplateプロパティを使った方法。
  • 3つ目は、Vueインスタンスのrenderプロパティを使った方法である。
  • templateプロパティを使う場合は、templateプロパティにhtml形式の文字列を直接指定する。("<p>Hello, {{name}}</p?")。あまり使わないらしい。
  • renderプロパティを使う場合は、renderプロパティに、仮想ノードを返却する関数を指定する。
  • renderプロパティで使う関数には仮想ノードを生成する関数が引数としてデフォルトで与えられるので、それを利用して仮想ノードを作る。
  • 内部的には、1つ目の書き方、2つ目の書き方は、3つ目のrenderに書き換えられている。

See the Pen template-render by popy1017 (@popy1017) on CodePen.

仮想DOMとは

  • まずDOMは、ドキュメントオブジェクトモデルの略で、htmlのようなウェブページの文書構造を保持するためのもので、ブラウザが持っているものである
  • 一方で、仮想DOMは、文書構造を保持するためのものである点はDOMと同じだが、こちらはJavascriptのオブジェクトとして保持される
  • なぜ仮想DOMが必要かというと、通常、ブラウザが保持しているDOMに対して、JavascriptなどでDOMを書き換える操作を行うと時間がかかる
  • そのため、例えば、表示している値に変更があって再描画する必要があるときに、いちいちすべてのDOMを書き換えてしまうと非常に遅くなってしまう。
  • それを防ぐためには、変更前と変更後のDOMの差分を見て、差分があるところだけを更新する必要があるが、変更後のDOMを作るのにも時間がかかってしまう。
  • そこで、その差分を検出するために使われるのが仮想DOMである。
  • 仮想DOMはJavascriptのオブジェクトなので、DOMの生成や更新に比べると、短い時間で生成や更新ができるため、変更前と変更後の仮想DOMを比較することで差分箇所を検知し、その部分だけDOMをいじるといったことが可能となる

Componentについて

  • Vueインスタンスは使い回しができないが、Componentを使うことで使い回しができるテンプレートを作成できる。

See the Pen component by popy1017 (@popy1017) on CodePen.

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@popy1017の技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう