Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8825

Vue.js コンポーネント

$
0
0

Vue.js コンポーネント

前回の記事はこちら
Vue.js フォーム入力バインディング

コンポーネントとは

ページを構成するUI部品で再利用可能なインスタンスです。

HTMLベースのテンプレートとjavascriptで書かれたロジックで構成されます。

コンポーネント使うメリットは以下です。

①再利用ができる

②メンテナンス性が高まる

グローバル登録

Helloと出力するコンポーネントを作成し複数回利用します。
jsfiddleで実際に記述しながら読むことをおすすめします。

index/html
<divid="app"><hello-component></hello-component><hello-component></hello-component><hello-component></hello-component></div><script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
Vue.component('hello-component',{template:'<p>Hello</p>'})varapp=newVue({el:'#app',})

実行結果
Image from Gyazo

コンポーネントの記述は第1引数にコンポーネント名を第2引数に処理内容を記述しましょう。

グローバル登録されたコンポーネントはすべてのVueインスタンスから利用可能です。

ローカル登録

特定のVueインスタンス配下でのみ利用するコンポーネントは
ローカル登録によってスコープ(範囲)を狭めることができます。

さきほどグローバル登録したコンポーネントをローカル登録に変更します。

index/html
<divid="app"><hello-component></hello-component><hello-component></hello-component><hello-component></hello-component></div><script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
varhelloComponent={template:"<p>Hello</p>"}varapp=newVue({el:'#app',components:{'hello-component':helloComponent}})

実行結果
Image from Gyazo

まず使用するVueインスタンスよりも先にコンポーネントを定義します。
次にvueインスタンス内のコンポーネントオプションにプロパティとして設定しましょう。

コンポーネント名

コンポーネント名を登録する際はハイフンを1つ以上含む(ケバブケース)必要があります。

例)
・hello-component OK
・button-counter OK
・hello NG
・helloComponent NG キャメルケースのためNG

理由は既に存在するHTMLや将来定義されるHTML要素との衝突を避けるためです。

ただしVue.jsのスタイルガイドではパスカル記法(全ての単語の先頭が大文字)を
推奨していますので状況に応じて混在しないように使い分けることをおすすめします。
Vue.jsスタイルガイド

index/html
<!--NG記述です--><divid="app"><hello></hello><hello></hello><hello></hello></div><script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
//NG記述ですvarhelloComponent={template:"<p>Hello</p>"}varapp=newVue({el:'#app',components:{'hello':helloComponent}})

※実行結果として動作しますが、仮に将来helloというタグがHTMLで定義された場合は衝突します。

コンポーネントのオプション

ボタンを押すとクリック数をカウントするコードをコンポーネントで記述しましょう。

index/html
<divid="app"><button-counter></button-counter><button-counter></button-counter><button-counter></button-counter></div><script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
Vue.component('button-counter',{data:function(){return{count:0}},template:'<button v-on:click="count++">{{ count }}</button>'})varapp=newVue({el:'#app'})

実行結果
Image from Gyazo

それぞれのボタンはカウント数を独自に保持しています。
これはコンポーネントを作成するたびに新しいインスタンスが作成されるためです。

コンポーネントのdataは直接定義されず関数となる必要があります。

index.js
//例 直接定義data:{count:0}//例 関数定義data:function(){return{count:0}}

理由は各インスタンスが独自にオブジェクトを利用できるようにするためです。

またテンプレートのルート要素は単一である必要があります。
上記のカウンターに"count:"のラベルをつけてみましょう。

index/html
<divid="app"><button-counter></button-counter><button-counter></button-counter><button-counter></button-counter></div><script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
Vue.component('button-counter',{data:function(){return{count:0}},template:'<span>count:</span><button v-on:click="count++">{{ count }}</button>'})varapp=newVue({el:'#app'})

実行結果
Image from Gyazo
Image from Gyazo

上記の記述ではspanとbuttonで要素が複数になっているためコンパイルエラーが発生します。
この場合はdivタグなどで囲んで要素を1つにまとめる必要があります。

index.js
//テンプレートを修正Vue.component('button-counter',{data:function(){return{count:0}},template:'<div><span>count : </span><button v-on:click="count++">{{ count }}</button></div>'//divで囲んで単数化})varapp=newVue({el:'#app'})

実行結果
Image from Gyazo

コンポーネント間の通信

複数のコンポーネントを並列または入れ子に配置された場合
スコープ(データの有効範囲)という概念が発生します。

コンポーネントで定義された情報(データ、メソッドなど)に
アクセスできるのはそのコンポーネントだけということになります。

次回はトランジションです。
Vue.js トランジション


Viewing all articles
Browse latest Browse all 8825


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>