【学習メモ】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" });