もふもふ技術部

IT技術系mofmofメディア

ReactよりイケてるらしいのでVue.jsに入門してみた

Reactのコードをたまにレビューすることがあるのですが、いつも記述量多いなーと感じていました。そんなとき、Vue.jsはもっとシンプルでいいよ!という悪魔の囁きを聞いたのでReactではなくVue.jsに入門してみることにしました。

インストール

基本的に公式ページが最新なので、公式ページを参考にします。日本語化されている。先人の努力の結晶や。ありがとう。

https://jp.vuejs.org/v2/guide/installation.html

devtoolを入れろと書いてあるので入れた。使い方はまだ知らん

https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd

npmと使ってインストールする。ぼくの環境では昔にインストールしたやつが入っているのか、特にnpm自体のセットアップは必要なかった。

$ npm install vue

cliツール入れろと書いてあるので言われるがままやってみる。

$ npm install --global vue-cli
# "webpack" ボイラープレートを使用した新しいプロジェクトを作成する
$ vue init webpack vue-tutorial
# 依存関係をインストールしてgo!
$ cd my-project
$ npm install
$ npm run dev

webpackとはなんぞや状態。

全部ちょいちょいなんか聞かれますが、面倒なのでそのままエンターキー連打でやり過ごす作戦。

? Project name vue-tutorial
? Project description A Vue.js project
? Author a.harada <redhornet96@gmail.com>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Setup unit tests with Karma + Mocha? Yes
? Setup e2e tests with Nightwatch? Yes

プロジェクトのテンプレートが出来上がったみたい。だがしかし動かし方が良くわからなかったので、そっと削除した。

チュートリアル

気を取り直して、次のチュートリアル的なの進めます。

https://jp.vuejs.org/v2/guide/index.html

ここを見ると初心者はvue-cliを使ってくれるなと書いてある。インストール手順の方でインストールしろって書いてあったから入れたのに!くっ

index.htmlファイルだけで完結してVue.jsのお試しが出来るみたい。それぞれのやってみたコードを貼っていく。

まず一つ目、Hello Vue!って表示された。divタグの中身のmessageがjs側でバインディングされた模様。

<html>
  <head>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app">
      {{ message }}
    </div>
    <script type="text/javascript">
      var app = new Vue({
        el: '#app',
        data: {
          message: 'Hello Vue!'
        }
      })
    </script>
  </body>
</html>

続いてこれ。Hover your mouse over me for a few seconds to see my dynamically bound title!というテキストにマウスカーソルをあわせてしばらく待つとYou loaded〜と表示される。

<html>
  <head>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app-2">
      <span v-bind:title="message">
        Hover your mouse over me for a few seconds
        to see my dynamically bound title!
      </span>
    </div>
    <script type="text/javascript">
      var app2 = new Vue({
        el: '#app-2',
        data: {
          message: 'You loaded this page on ' + new Date().toLocaleString()
        }
      })
    </script>
  </body>
</html>

次は表示/非表示切り替えかな。seenをfalseにしたら非表示になった。

<html>
  <head>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app-3">
      <p v-if="seen">Now you see me</p>
    </div>
    <script type="text/javascript">
      var app3 = new Vue({
        el: '#app-3',
        data: {
          seen: true
        }
      })
    </script>
  </body>
</html>

ループはv-forだけで表現出来るみたい。これはイケてる感やばい。

app4.todos.push({text: 'hogehoge'})と入力してみると新しく画面にも追加された。わーイケてる。

<html>
  <head>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app-4">
      <ol>
        <li v-for="todo in todos">
          {{ todo.text }}
        </li>
      </ol>
    </div>
    <script type="text/javascript">
      var app4 = new Vue({
        el: '#app-4',
        data: {
          todos: [
            { text: 'Learn JavaScript' },
            { text: 'Learn Vue' },
            { text: 'Build something awesome' }
          ]
        }
      })
    </script>
  </body>
</html>

こんどはボタンを押すとテキストがリバースされる。イベントリスナーとか気にしないで実装出来るの楽だー。

<html>
  <head>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app-5">
      <p>{{ message }}</p>
      <button v-on:click="reverseMessage">Reverse Message</button>
    </div>
    <script type="text/javascript">
      var app5 = new Vue({
        el: '#app-5',
        data: {
          message: 'Hello Vue.js!'
        },
        methods: {
          reverseMessage: function () {
            this.message = this.message.split('').reverse().join('')
          }
        }
      })
    </script>
  </body>
</html>

inputに入力したテキストがそのままpタグ内に表示される。こちらもイベントリスナーなしで実装できる。

<html>
  <head>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app-6">
      <p>{{ message }}</p>
      <input v-model="message">
    </div>
    <script type="text/javascript">
      var app6 = new Vue({
        el: '#app-6',
        data: {
          message: 'Hello Vue!'
        }
      })
    </script>
  </body>
</html>

続いてコンポーネントについて。上の例ではliタグで直接TODOリストを表現していたのですが、liタグをtodo-itemというコンポーネントでラップする。コンポーネントに切り出すことで、一部品のなかでロジックを完結させられるようになる。

最後なのでこれだけ画像アップしとくわ。

<html>
  <head>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app-7">
      <ol>
        <!--
          todo オブジェクトによって各 todo-item を提供します。
          それは、内容を動的にできるように表します。
          また後述する "key" で各コンポーネントに提供する必要があります。
        -->
        <todo-item v-for="item in groceryList" v-bind:todo="item"></todo-item>
      </ol>
    </div>
    <script type="text/javascript">
      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' }
          ]
        }
      })
    </script>
  </body>
</html>

component

ざっくりどういうことが出来るかわかった。次はRails上で使う方法を試してみたい。