Vueのデータバインディング
追記(6/15)
- バインディングとは、データとUIを結びつけること
- 双方向とは、データを更新⇄UIを更新
- dataで、データを保持させる
→name(プロパティ)とvalueのセット。 - {{ }}にはjsの式も書ける
→
new Vue
はVue.jsの心臓部分みたいなもの。- Vueインスタンスのelで、Vueがどの部分のテンプレートを扱うか判断してくれる(VueインスタンスをDOM要素(HTMLとか)に紐付ける)
→el: '#app'
→<div id='app'>
に紐付く。 マスタッシュ構文
{{ 〇〇 }}
を使うことで、テンプレート内のデータオブジェクトにアクセスできる。
→{{ }}内にはJavascriptの記述ができる。{{ name.toUpperCase }}
とか。独自メソッドも記述できる。{{ 〇〇 }}
→ dataのmessageにアクセス
→dataのmessageの値がマスタッシュ構文内のmessageに代入される。
→{{ data.message }}
ではなく{ message }
と記述することに注意。
<div id='app'> {{ message }} </div> <script> new Vue({ el: '#app', data: { message: 'Hello World!' } }) </script>
当たり前だけど、以下はHTMLではなくテンプレート(v-forとかもテンプレート)を書いている。そしてVueがテンプレートの記述を見て「あ、これはテンプレート構文だ!」と判断して、HTMLに変換して出力してくれる。それをブラウザが受け取って画面に表示してくれるって感じ。
<div id='app'> {{ message }} </div>
データバインディングとは?
データと出力(描画)を同期する仕組み
「v-」から始まるディレクティブ(命令)
v-bind
モジュールの値をコンポーネントに出力する。HTML要素のデータをバインドできる。
v-bind:引数="js側のプロパティ"
という形で記述する。引数にはinputタグならvalue、aタグならhrefとか、タグにあった属性を記述する。
:引数="js側のプロパティ"
に省略可能。
<div id="app"> <input :value="message"> </div> <script> new Vue({ el: '#app', data: { message: 'Hello World!' } }) </script> >> Hello World!
他にも[ ]を使った記述もできる。
Hello World!というリンクが表示される。
<div id="app"> <!-- <a href='https:google.com'> と同じ --!> <a :[attribute]="url">Twitter</a> </div>
<script> new Vue({ el: '#app', data: { url: 'https://google.com', attribute: 'href' } }) </script>
>> Hello World!
更にv-bindでバインドする内容をオブジェクト形式で記述できる。
<div id="app"> <!-- <a href='https://twitter.com', id=21> と同じ --!> <a v-bind="{href: urlTwitter, id: number}">Twitter</a> </div>
<script> new Vue({ el: '#app', data: { urlTwitter: 'https://twitter.com', number: 21 } }) </script>
更にVue側にオブジェクトの中身を記述することもできる。
<div id="app"> <!-- <a href='https://twitter.com', id=21> と同じ --!> <a v-bind="twitterObject">Twitter</a> </div>
<script> new Vue({ el: '#app', data: { twitterOblect: { href: 'https://twitter.com', id: 21 } }) </script>
v-ifディレクティブ
HTMLの要素を表示、非表示
→非表示の時、要素ごと消える(DOMレベルで削除)
→表示で要素を再構築
<div id="app"> <h1 v-if="flag">Vue is Good!</h1> <h1 v-else>Vue is Bad!</h1> </div> <script> new Vue({ el: '#app', data: { flag: true } }) </script>
v-forディレクティブ
ループ処理
<タグ名 v-for="変数名 in 配列名"> {{ 変数名 }} </タグ名>
data内に記述した配列の要素が{{ item }}
に代入される。
data内の配列がel
によって#app
と紐づいて、v-forでdata内の要素が順にitemに代入されるって感じ。
<ul id="app"> <li v-for="item in list">{{ item }}</li> </ul> <script> new Vue({ el: '#app', data: { list: ['Vue', 'React', 'Angular'] } }) </script>
v-on
v-on:click
を@click
に省略できる
<タグ名 v-on: イベント名 = "ハンドラ名"> 表示したい文字 </タグ名> methods: { ハンドラ名: 関数名() { 処理 } }
これでクリックするたびに数値がカウントされていく
<div id="app"> <span>{{ count }}</span> <button @click="increment">+</button> ← +ボタン </div> <script> new Vue({ el: '#app', data: { count: 0 }, methods: { increment: function() { this.count++ } } }) </script>
ついでに
双方向バインディングとは
v-bind
だと、HTML側の値を変更したとしても、モジュールの値は変更されない。
そこで双方向バインディングを使えば、プレビュー(HTML)側で入力した内容が、モジュール側の値を変更してくれる。
→入力内容を変更したことでデータの更新がなされ、DOMに反映される。
v-model ディレクティブ
v-bindとv-onの2つの処理を組み合わせたもの。
- inputにv-model="message"
→inputのフォームに入力した値が{{ message }}に結びつく。
<タグ名 v-model = "プロパティ名">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <div id="app"> <p>{{message}}</p> <input v-model="message"> </div> <script> new Vue({ el: '#app', data: { message: 'Hello World!' } }) </script>
<input v-model="message">
にdata: { message: 'Hello World!' }
のHello worldが入ってて、{{message}}にHello worldが表示される。
→inputを書き換えると{{message}}も書き換わる
component
Webサイトの画面はヘッダー、メイン、フッター、サイドバーなど色々な部品から構成される。
コンポーネントを使えば、部品ごとにHTML, CSS, JSを1セットにできる。
→変更箇所の発見、メンテナンスが容易になる、
Vue.component('コンポーネント名', {コンポーネントのオブジェクト}) Vue.component('my-component', { template: '<li>Hello World!</li>'})
コンポーネントは再利用が可能
<script src="https://cdn.jsdelivr.net/npm/vue"></script> <div id="app"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> <script> Vue.component('my-component', { template: '<li>Hello World!</li>' }) new Vue({ el: '#app' }) </script> >> ・ Hello World! ・ Hello World! ・ Hello World!
コンポーネントの親子間のデータの受け渡し
<div id="app"> <my-component :message="'hoge'"></my-component> <my-component :message="'fuga'"></my-component> <my-component :message="'hogefuga'"></my-component> </div> <script> Vue.component('my-component', { props: ['message'], template: '<li>{{ message }} </li>' }) new Vue({ el: '#app' }) </script> >> ・hoge ・fuga ・hogefuga