はじめに
軽量JSフレームワークとして有名なVue.js。
最近、Laravelに触れる機会が増えたことと、以前からRails + Vueという構築を耳にするので、今更ではありますが勉強を始めようと思います。
今回は基本文法に関してメモしていきます。
なお、Vue.jsの公式ドキュメントはこちらになります。
https://jp.vuejs.org/
使用ツール
今回はJSFiddleを使用して開発します。
公式でも進められており、今回のような簡単な文法を試すくらいであればちょうど良いのかな、と思います。
なお、使用する場合はJavaScriptのFWをVue.jsの2系にします。
今回扱う内容は、公式ドキュメントに依ります。
基本文法
JSFiddleで試すので、HTML、CSS、JS(Vue)を分けて記述していきます。
レンダリング
HTMLテンプレートの中にデータを埋め込む場合です。
HTML
1 2 3 | <div id="app"> {{ message }} </div> |
JS
1 2 3 4 5 6 | var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }) |
Vueインスタンスを生成します。
el
が対象のDOMを指定しています。
また
data
で定義した値を
{{ }}
の中に埋め込みます。
ちなみにリアクティブなので、Consoleから値を渡せば変更されます。
その際、JSFiddleで実施する場合はConsoleのコンテキストタブを「result (fiddle.
1 | window.app = app; |
ディレクティブ
HTML
1 2 3 4 5 6 | <div id="app-2"> <span v-bind:title="message"> 数秒間この上にマウスオーバーしておくと、 バインドしたタイトルを見ることができます! </span> </div> |
JS
1 2 3 4 5 6 | var app2 = new Vue({ el: '#app-2', data: { message: 'あなたがこれをロードした時間は' + new Date() } }) |
v-bind
で対象の属性をVueインスタンスの
message
プロパティで保存できます。
v-
は接頭辞で他にも種類があります。
v-bind (Vue.jsリファレンス)
この結果、HTMLでは以下のようにレンダリングされます。
1 2 3 4 | <span title="あなたがこれをロードした時間はMon Jun 19 2017 20:56:20 GMT+0900 (JST)"> 数秒間この上にマウスオーバーしておくと、 バインドしたタイトルを見ることができます! </span> |
条件分岐とループ
条件分岐(v-if)
HTML
1 2 3 | <div id="app-3"> <p v-if="seen">Hi!!</p> </div> |
JS
1 2 3 4 5 6 7 8 | var app3 = new Vue({ el: '#app-3', data: { seen: true } }) window.app = app3; |
v-if
ディレクティブで
seen
の真偽値を確認して表示制御できます。
試しに
seen
をfalseにすると表示されなくなります。
v-if (Vue.jsリファレンス)
ループ文(v-for)
HTML
1 2 3 4 5 6 7 | <div id="app-4"> <ol> <li v-for="todo in todos"> {{ todo.text }} </li> </ol> </div> |
JS
1 2 3 4 5 6 7 8 9 10 11 12 | var app4 = new Vue({ el: '#app-4', data: { todos: [ { text: 'Studying JavaScript' }, { text: 'Studying PHP' }, { text: 'Studying Ruby' }, ] } }) window.app = app4; |
v-for
ディレクティブを使用することで、リストを展開できます。
v-for (Vue.jsリファレンス)
なお、コンソールで下記を入力すれば追加されます。
1 | app.todos.push({ text: 'Studing CSS' }) |
ユーザー入力の制御
イベントリスナの追加(v-on)
HTML
1 2 3 4 5 6 | <div id="app-5"> <p>{{ message }}</p> <button v-on:click="reverseMessage"> Reverse Message </button> </div> |
JS
1 2 3 4 5 6 7 8 9 10 11 | var app5 = new Vue({ el: '#app-5', data: { message: 'Hello Vue.js!' }, methods: { reverseMessage: function() { this.message = this.message.split('').reverse().join('') } } }) |
v-on:click
で、クリック時のイベントを定義できます。
v-on (Vue.jsリファレンス)
その際、インスタンス内の
methods
で関数を作成すればその処理をしてくれます。
双方向バインディング(v-model)
ビュー側でデータが変更された場合、反映してほしいと思います。
v-model
を使用することでそれができます。
v-model (Vue.jsリファレンス)
HTML
1 2 3 4 | <div id="app-6"> <p>{{ message }}</p> <input v-model="message"> </div> |
JS
1 2 3 4 5 6 | var app6 = new Vue({ el: '#app-6', data: { message: 'Hello Vue!' } }) |
入力フォームから変更することで、
message
も変更されます。
試しにコンソールで確認してみると、「Hello Vue!」ではなく、「hogehoge」になっています。
1 2 | app.message > "hogehoge" |
コンポーネント
再利用可能なまとまりに分けておくことができます。
JS(コンポーネント)
1 2 3 4 | Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' }) |
これで、
todo-item
というコンポーネントにまとめることができます。
propsで
todo
という値を受け取ることができます。
template
は埋め込むHTMLテンプレートになります。
これで
<todo-item>
というタグをHTMLに記述すれば使用可能です。
HTML
1 2 3 4 5 | <div id="app-7"> <ol> <todo-item v-for="item in groceryList" v-bind:todo="item"></todo-item> </ol> </div> |
v-bind
で
todo
にループ文で取り出した
item
をバインドさせます。
これでコンポーネントに値を渡せます。
JS(Vueインスタンス)
1 2 3 4 5 6 7 8 9 10 | var app7 = new Vue({ el: '#app-7', data: { groceryList: [ { id: 0, text: 'Vegetables' }, { id: 1, text: 'Cheese' }, { id: 2, text: 'Whatever else humans are supposed to eat' }, ] } }) |
コンポーネントとインスタンスを合わせて書くと、以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' }) var app7 = new Vue({ el: '#app-7', data: { groceryList: [ { id: 0, text: 'Vegetables' }, { id: 1, text: 'Cheese' }, { id: 2, text: 'Whatever else humans are supposed to eat' }, ] } }) |
さいごに
今回は以上になります。
上記は公式ドキュメントではこちらの範囲になります。
次回はVueインスタンスになります!
2017-07-06 追記
次の記事ができました!
Vue.js入門その2〜Vueインスタンスってなんぞ?〜