コンポーネント
コンポーネントとは
コンポーネントとは名前付きの再利用可能な Vue インスタンス
必要なだけ何度でも再利用できるが、宣言するたびに別のインスタンス
扱いになる為、内部に保持している変数は別で保持される。
また、「template」で設定するルート要素は単一のみなので、
複数の要素がある場合はdiv
で囲う必要がある。
ローカルで定義
登録したVueインスタンス配下でしか使えない。
コンテンツのサイズがグローバルのものより小さくなる
またローカルで定義した場合は削除して良いものかの判断がつきやすくなる為、
基本はローカルで定義したほうが良い
グローバルで定義
グローバルに定義されるため、一度定義すれば、どこからでも呼び出すことができる。
多く定義すると、ビルドの時間が長くなるので共通で使用するものだけ定義するべき
dataは関数で定義する必要がある。
各インスタンスが返されるデータオブジェクトを独立のものにする為にこうなっている
また、componentを定義する際は、Vueインスタンス作成前に記載する必要がある
ちなみにdata部分はES6以上であれば短縮形で記載できる
Vue.component('button-counter',{ data(){ return{ count:0 } }, template:'<div><span>count:<span><button v-on:click="count++">{{count}}</button></div>' }) const app = new Vue({ el:"#app" })
コンポーネントの親子構造について
コンポーネントも親子構造の関係を持つことができる。
ようは、下記のように親コンポーネントの中に子コンポーネントを記載し、テンプレートを呼び出すことができる。
コンポーネント間のデータのやり取り
基本的にコンポーネントで定義したdata
はそのままでは使用できないため、
アクセスできるようにする必要がある。
そのためにprops
オプションが使える。
また、子コンポーネントから親コンポーネントへ値を渡す場合には、$emit
メソッドを使用する。
propsオプション
propsの値は直接変更することができない。
厳密に言うと、const
のように再代入ができないだけで
オブジェクトのプロパティは変更できるので、注意が必要。
またtype
で型の制限をすることができる。
$emitメソッド
$emitメソッドの第一引数には親で定義したイベント名を定義
二つ以上の引数がある場合はその値を親コンポーネントへ渡す
親コンポーネントから子コンポーネントへデータを渡す
流れとしては、親コンポーネント内でv-bind
で渡した値を子コンポーネント
で受け取って表示する流れになっている。
子コンポーネントから親コンポーネントへデータを渡す
下記プログラムの説明は、
親コンポーネントで「@update:user-name」のイベントハンドラが実行される
第二引数には変更された名前を戻り値として返す。
//子コンポーネント const UserForm = { template: ` <div> <div>ユーザー名変更フォーム</div> <input v-model='user_name' /> <button @click='update'>名前変更</button> </div> `, props: { userName: { type: String, required: true } }, data() { return { user_name: this.userName } }, methods: { update () { this.$emit('update:user-name', this.user_name) } } }
下記プログラムの説明は、
名前変更ボタン押下時に子コンポーネントのupdateメソッドで実行された$emit
の処理が
親コンポーネントに戻ってきたときに、$emit
の第二引数で設定されたものが
$event
に入っているのでそれをuser_name
の変数に代入している。
//親コンポーネント const UserDetail = { components: { 'user-form': UserForm }, data() { return { user_name: 'ヤマダ タロウ' } }, template: ` <div> <div> <span>ユーザー名: {{ user_name }}</span> </div> <div> <user-form :user-name='user_name' @update:user-name='user_name = $event'></user-form> </div> <pre>{{user_name}}</pre> </div> ` }
子コンポーネントから親コンポーネントへデータを渡す(.sync修飾子を使う)
.sync修飾子を使うことで短く書くことができる。
変更後は下記
変更箇所は
<user-form :user-name.sync='user_name'></user-form>
と
this.$emit('update:userName', this.user_name)
の所。userName
はPropで宣言した変数名を記載する。
.sync修飾子とは
2.3.0からの機能で、子でプロパティが変更されたときに親でも変更できるようになる。
スロット
コンポーネントの外部からコンポーネント内のテンプレートの任意の場所にHTMLを展開することができる
htmlのtemplate要素
はVue.jsで使われるダミーの要素この中でslot属性
が定義された場合
template要素内の記載がレンダリングされる
html側で特にslot属性
の記載がない場合は、<slot></slot>
の部分にレンダリングされる。
span要素
の中にslot属性
を記載した場合は、span要素
ごとレンダリングされる