Vue.js始めるおれおれアドベントカレンダー2016 – 2日目

すぐ触れるやつ

試したい場合はこちらでどうぞ。

コンストラクター

new Vue({ el: selector }) で生成。

<div id="app">
  <h1>My First App</h1>
</div>
var vm = new Vue({
  el: '#app',
});

el: $('body').children().first().get(0) みたいに、セレクターの代わりにDOMオブジェクトでもいける。(jQueryオブジェクトではない。)

data でデータ

<div id="app">
  <h1>{{message1 + message2}}</h1>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    message1: 'Hello ',
    message2: 'World!',
  },
});

computed で動的情報

「算出プロパティ」(Computed Properties) と呼ぶみたい。

<div id="app">
  <h1>Welcome {{fullName}}!</h1>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    firstName: 'Ginpei',
    lastName: 'Takanashi',
  },
  computed: {
    fullName: function() {
      return this.firstName + ' ' + this.lastName;
    },
  },
});

めっちゃ便利っぽい。

しかも計算結果はキャッシュされ、使用情報(今回なら firstNamelastName )が更新された場合だけ再実行されるとか。すごい。

methods でメソッド

単数形 method ではない。(百万回くらい間違えた。)

<div id="app">
  <button v-on:click="hello_click">Hello</button>
</div>
var vm = new Vue({
  el: '#app',
  methods: {
    hello_click: function(event) {
      alert('Hello!');
    },
  },
});

あー言ってるそばから method と書いてしまった……。(修正した。)

computed があるので、単純な画面出力に使う場面は少なさそう?

components でコンポーネント

v-bind で情報を与えて、 props で名前を指定して受け取る。

<div id="app">
  <app-title v-bind:title="'Sugoi Yo!'"></app-title>
</div>
// <app-title>
var appTitle = {
  template: '<h1>{{title}}</h1>',
  props: [ 'title' ],
};

// Main
var vm = new Vue({
  el: '#app',
  components: {
    appTitle: appTitle,
  },
});

情報は v-bind:foo で与え、 props で受け取る。一度受け取った情報はコンポーネント側に所属?するようになり、変更は親へ通知されないみたい。今回やってないけどイベントハンドラーも v-bind で渡す。

奥が深そうなので別にします。また今度詳しく見る。

ちなみにES2015 (ES6) で追加された文法だと、 { appTitle: appTitle } の代わりに短く { appTitle } と書ける。

watach で値を監視

あんまり使わなさそ。いやでも外部ライブラリと連携したりするときにもりもり使うか。

<div id="app">
  <label>
    Search:
    <input v-model="keyword" type="search" />
  </label>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    keyword: '',
  },
  watch: {
    keyword: function(keyword) {
      var url = '/search?keyword=' + this.keyword;
      axios.get(url)
        .then(function(response) {
          // ...
        })
    },
  },
});

とはいえ変更の瞬間に通信開始してもアレだな。 throttling が必要?

テンプレートで出力

文字列を表示する

コンストラクターの data に除法を格納、テンプレートの {{key}} で出力。HTMLエスケープされる。

<div id="app">
  <p>{{message}}</p>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    message: '<b>BOLD</b>',
  },
});

data 以外の方法でも同様。JavaScriptコードを書けるので、 {{message.trim()}} とかしても良い。でもたぶん computed に入れちゃった方が良いよね。

HTMLを出力する

v-html で指定すると、HTMLをそのまま出力する。

<div id="app">
  <p v-html="message"></p>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    message: '<b>BOLD</b>',
  },
});

Vue使ってるとあんまりそういうことなさそう。外部サービスのやつを埋め込むときとか?

テンプレートの制御

v-show で表示切替

<div id="app">
  <label><input v-model="visible" type="checkbox" /> Visible</label>
  <p v-show="visible">Hello!</p>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    visible: false,
  },
});

v-hide はないみたい。

v-if で表示切替

あと v-else-if (v2.1+)と v-else も。

<div id="app">
  <select v-model="language">
    <option value="en">English</option>
    <option value="ja">Japanese</option>
    <option value="ja_KS">Kansaian</option>
  </select>
  <div v-if="language==='en'">
    <h1>Hello!</h1>
  </div>
  <div v-else-if="language==='ja'">
    <h1>こんにちは!</h1>
  </div>
  <div v-else>
    <h1>☺</h1>
  </div>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    language: 'en',
  },
});

v-else-if はあんまり使わない方が良いんじゃいかなあ。

v-for で繰り返し出力

<div id="app">
  <ul>
    <li v-for="name in names">{{name}}</li>
    <li v-for="i in 3">{{i}}</li>
  </ul>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    names: [
      'Alice',
      'Bob',
      'Charlie',
    ],
  },
});

v-for="value in object" とか v-for="(value, key) in object" とか も使えるらしい。デバッグ時に便利かも。

あと v-for="i in 999" と数字を指定して繰り返せるのも、デザイン考えるときにダミー出力するのに使えそう。

インタラクション

v-on でイベント監視

<div id="app">
  <form v-on:submit.prevent="form_submit">
    <input type="search" />
    <button>Search</button>
  </form>
</div>
var vm = new Vue({
  el: '#app',
  methods: {
    form_submit: function(event) {
      // preventDefault不要!
    },
  },
});

.prevent を付けると自動で event.preventDefault() を呼び出しておいてくれる。おお、これべんり。

v-model でフォーム入力値

<div id="app">
  <p>{{message}}, {{available}}, {{number}}</p>
  <p><input v-model="message" type="text" /></p>
  <p><input v-model="available" type="checkbox" /></p>
  <p><input v-model.number="number" type="number" /></p>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    available: true,
    message: 'abc',
    number: 100,
  },
});

いわゆる双方向バインディングってやつかしら。フォーム側で変更すると即座に反映される。

.number を付けると数値に変換して操作してくれる。これ便利! これでもう '1' + '2''12' になってしまうようなアレに悩まされることもなくなるのでは。

あとフォームの種類は豊富だけど、チェックボックスなら真偽値に、みたいな感じでなんかうまいことやってくれるっぽい。

そんな感じ。

そんなにたくさん覚えなくちゃいけない感じではないけど、 v-on.submit.prevent みたいな便利なやつがちょくちょく 追加されて良い感じの感じでした。

参考