【学習メモ】Vue.js入門 基礎から実践アプリケーション開発まで その2
3 コンポーネントの基礎
3.2 Vue コンポーネントの定義
3.2.1 グローバルコンポーネントの定義
<!-- グローバルコンポーネント -->
<div id="app">
<fruits-list-title></fruits-list-title>
<fruits-list-description></fruits-list-description>
<fruits-list-table></fruits-list-table>
<fruits-list></fruits-list>
</div>
// グローバルコンポーネント
Vue.component("fruits-list-title", {
template: `<h1>一覧</h1>`
});
Vue.component("fruits-list-description", {
template: `<p>ここに説明が入ります</p>`
});
Vue.component("fruits-list-table", {
template: `
<table>
<tr>
<th>季節</th>
<th>フルーツ</th>
</tr>
<tr>
<td>春</td>
<td>いちご</td>
</tr>
<tr>
<td>夏</td>
<td>スイカ</td>
</tr>
</table>
`
});
// 子コンポーネント
Vue.component("fruits-list", {
template: `<div><fruits-list-table></fruits-list-table></div>`
});
// Vue のマウント
var app = new Vue({
el: "#app"
});
3.2.3 ローカルコンポーネントの定義
<!-- ローカルコンポーネント -->
<div id="app">
<fruits-list-title></fruits-list-title>
<fruits-list-description></fruits-list-description>
<fruits-list-table></fruits-list-table>
<fruits-list></fruits-list>
</div>
// ローカルコンポーネント
// Vue のマウント
var app = new Vue({
el: "#app",
components: {
"fruits-list-title": {
template: `<h1>一覧</h1>`
},
"fruits-list-description": {
template: `<p>ここに説明が入ります</p>`
},
"fruits-list-table": {
template: `
<table>
<tr>
<th>季節</th>
<th>フルーツ</th>
</tr>
<tr>
<td>春</td>
<td>いちご</td>
</tr>
<tr>
<td>夏</td>
<td>スイカ</td>
</tr>
</table>`
}
}
});
3.3 コンポーネント間の通信
親コンポーネント → 子コンポーネント への通信: props
子コンポーネント → 親コンポーネント への通信: event
3.3.1 親コンポーネントから子コンポーネントへデータ伝播
props の例
<!-- 親が `fruits-component` にマウントされたインスタンス -->
<div id="app">
<ol>
<!-- `v-for` で繰り返した各fruitを `props(fruits-item)に与えている` -->
<fruits-item-name
v-for="fruit in fruitsItems"
:key="fruit.name"
:fruits-item="fruit"
></fruits-item-name>
</ol>
</div>
Vue.component("fruits-item-name", {
props: {
fruitsItem: {
// テンプレート中ではケバブケース
type: Object, // オブジェクトかどうか
required: true // このコンポーネントには必須なので `true`
}
},
template: "<li>{{fruitsItem.name}}</li>"
});
// Vue のマウント
var app = new Vue({
el: "#app",
data: {
// 親では配列だが、`v-for` で `Object` として渡している
fruitsItems: [{ name: "梨" }, { name: "いちご" }]
}
});
3.3.2 子コンポーネントから親コンポーネントへデータ伝播
カスタムイベントを使用
<!-- カスタムイベントを `v-on` で補足 -->
<div id="app">
<div v-for="fruit in fruits">
{{ fruit.name }}:
<counter-button v-on:increment="incrementCartStatus()"></counter-button>
</div>
<p>合計: {{ total }}</p>
</div>
var counterButton = Vue.extend({
template: `<span>{{counter}}個<button v-on:click="addToCart">追加</button></span>`,
data: function() {
return {
counter: 0
};
},
methods: {
addToCart: function() {
this.counter += 1;
this.$emit("increment"); // `increment`カスタムイベントの発火
}
}
});
// Vue のマウント
var app = new Vue({
el: "#app",
components: {
"counter-button": counterButton
},
data: {
total: 0,
fruits: [{ name: "梨" }, { name: "いちご" }]
},
methods: {
incrementCartStatus: function() {
this.total += 1;
}
}
});
3.4 コンポーネント間の設計
3.3.4 ログインフォームコンポーネントの作成
<div id="login-example"><user-login></user-login></div>
// コンポーネントの定義
Vue.component("user-login", {
template: `
<div id="login-template">
<div>
<input type="text" placeholder="ログインID" v-model="userid">
</div>
<div>
<input type="password" placeholder="パスワード" v-model="password">
</div>
<button @click="login()">ログイン</button>
</div>
`,
data: function() {
return {
userid: "",
password: ""
};
},
methods: {
login: function() {
auth.login(this.userid, this.password);
}
}
});
var auth = {
login: function(id, pass) {
window.alert("userid:" + id + "\n" + "password:" + pass);
}
};
// Vue のマウント
var app = new Vue({
el: "#login-example"
});