21
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue.js少しだけいじった

Posted at

話題のVue.js、公式サイト見ながらサンプルコード写経したりしてみた。
Vue.js

こういうフレームワーク系ほぼ触ったことなかったので、サンプルコードレベルでも便利さに感動w

以下の記事も参考にしてます。

準備

とりあえずサンプルコードいくつか書こうと思ったので、プロジェクトのディレクトリ作成、htmlというディレクトリ下にHTMLを、jsというディレクトリにJavaScript置くことに。

coffeescriptで書きたかったので、ストリーミングビルドシステムgulpでタスクを作ってcoffeescriptをコンパイルすることに。
(大した規模じゃないのでぶっちゃけ必要ない...)

グローバルにcoffee-script, gulpをインストール。そのあとプロジェクトのディレクトリでライブラリインストール。

$ npm install -g gulp coffee-script
$ npm init
$ npm install --save-dev gulp gulp-coffee coffee-script

gulpfileもcoffeeで。

gulpfile.coffee
gulp   = require 'gulp'
coffee = require 'gulp-coffee'

gulp.task 'coffee', () ->
  gulp.src './coffee/*.coffee'
      .pipe coffee()
      .pipe gulp.dest('./js')

いったん手動でコンパイルできれば良いかという感じだったので、上記のようにcoffeeというタスクを一個作って終わり。gulp coffeeコマンドで、coffeeディレクトリ以下に置いた*.coffeeファイルをコンパイルし、jsディレクトリ以下にjsファイルを作る。

今回はやってないが、coffeescriptのファイルを監視して、変更があったら自動でコンパイルするのもgulpで可能なはず。

ディレクトリの構成は以下。

.
├── coffee
│   └── hello_vue.coffee
├── gulpfile.coffee
├── html
│   └── hello_vue.html
├── js
│   └── hello_vue.js
├── package.json
└── node_modules

サンプル1 (簡易Todoリスト)

todo_example.coffee
demo = new Vue
  el: '#demo',
  data: {
    title: 'todos',
    todos: [
      {
        done: true,
        content: 'Learn JavaScript'
      },
      {
        done: false,
        content: 'Learn Vue.js'
      }
    ]
  }
todo_example.html
<html>
  <head>
    <title>Vue.js sample</title>

    <style>
    body {
      font-family: Helvetica Neue, Arial, sans-serif;
    }
    li.done {
      text-decoration: line-through;
    }
    </style>
  </head>
  <body>
    <div id="demo">
      <h1>{{title | uppercase}}</h1>
      <ul>
        <li
          v-repeat="todos"
          v-on="click: done = !done"
          class="{{done ? 'done' : ''}}">
          {{content}}
        </li>
      </ul>
    </div>

    <script src="http://cdnjs.cloudflare.com/ajax/libs/vue/0.10.6/vue.min.js"></script>
    <script src="../js/todo_example.js"></script>
  </body>
</html>

Vueクラスのインスタンス作成時のオプションとして、eldataを利用。

  • el: これで指定したHTML要素がVue.jsの管理下となり、ViewModelに紐付けられる
  • data: 上記ViewModelにバインドする値

また、html側でデータバインディングに利用するディレクティブv-repeatv-onを利用、さらにFilterも利用。{{}}はデータバインディングに利用する記法で、値が出力される。

  • v-repeatで、バインディングした配列todosによって子ViewModelを作成
  • v-onのところで、クリック時に、バインディングした値doneをtrue <=> falseに変更するよう設定
  • h1タグの部分で、uppercaseというFilterを利用。|で区切って呼び出すことで、バインディングした値に処理を行う。今回は大文字化。

※理解がまだ浅いので、解釈が誤っている恐れあり

実際に出力されるHTML(の一部)は以下。バインディングした値がリスト表示され、クリックするごとにclassが切り替わる。この挙動を上記のようにシンプルなjsのコードで表現できる。

todo.html
<div id="demo">
  <h1>TODOS</h1>
  <ul>
    <li class="done">
      Learn JavaScript
    </li><li>
      Learn Vue.js
    </li><!--v-repeat-todos-->
  </ul>
</div>

サンプル2 (markdownエディタ)

markdown.coffee
editor = new Vue
  el: '#editor',
  data: {
    input: '# hello'
  },
  filters: {
    marked: marked
  }
markdown.html
<html>
  <head>
    <title>Vue.js sample</title>
    <style>
      html, body, #editor {
        margin: 0;
        height: 100%;
        font-family: 'Helvetica Neue', Arial, sans-serif;
        color: #333;
      }

      textarea, #editor div {
        display: inline-block;
        width: 49%;
        height: 100%;
        vertical-align: top;
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
        padding: 0 20px;
      }

      textarea {
        border: none;
        border-right: 1px solid #ccc;
        resize: none;
        outline: none;
        background-color: #f6f6f6;
        font-size: 14px;
        font-family: 'Monaco', courier, monospace;
        padding: 20px;
      }

      code {
        color: #f66;
      }
    </style>
  </head>

  <body>
    <div id="editor">
      <textarea v-model="input"></textarea>
      <div v-html="input | marked"></div>
    </div>

    <script src="http://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js">
    </script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/vue/0.10.6/vue.min.js"></script>
    <script src="../js/markdown.js"></script>
  </body>
</html>

markdownをパースできるように、marked.jsを利用。

インスタンス作成のオプションとしてfiltersを利用。先の例でも出てきたようにHTML側で利用する。

HTML側ではv-modelv-htmlといったディレクティブを使用。

  • v-modelで、textareaタグ内にバインディングした文字列を展開
  • v-htmlで、バインディングした文字列をフィルタリング(marked.jsでパース)したHTMLを該当div内に展開

実際に出力されるHTML(の一部)は以下のようになり、バインディングした# helloという文字列がmarkdownとして認識され、divタグ内でh1タグ内になっているのが分かる。当然Vue.jsによって双方向にデータバインディングされているため、textareaの中身を編集すれば、隣のdiv内のHTMLも変更される。

markdown.html
<div id="editor">
  <textarea></textarea>
  <div><h1 id="hello">hello</h1>
  </div>
</div>

おわり

まだまだ手に馴染んでいないが、Vue.js、触っててかなり面白い。引き続きべんきょうする

21
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?