Vue.js + Vueify + gulpでプロトタイピングぽいことをする

# はじめに…

最近WebViewを使うプロジェクトに関わっているのもあって、iOSやAndroidだけではなくWeb関連の技術も追っかけなくてならない状態です。故に、デバイスはモバイルだけではなくデスクトップもウェアラブルも全て対応範囲の視野にいれておかなければならないため、既存のプロトタイピングツールでは対応しきれないシーンに度々出会います。

# プロトタイピングツールって

プロトタイピングツールは色々あります。画像ベースのものから、Scriptベースなどなど。しかし、次のような問題点でInVisionでさえもどかしい思いをしています。


### **画像ベースのプロトタイピングツールの問題点**

1. **結局全てのステートに合わせたカンプをつくらなくてはならない。**
2. **条件分岐でデザインの一部を変更したい**
3. **デザイナーが少数の環境ではプレビュー共有くらいでしか使えない。**
4. **インタラクションや動線を選ぶのは面倒くさい。**
5. **そもそもインタラクションをいれることがプロダクトの本質ではない。**
6. **既に運用されているプロダクトへのコミットが難しい。**
7. **クリッカブルが座標なのでカンプが変わると位置がズレる…ウザい。**

プロトタイプは、実機確認に近い状態でデザイナー以外が確認できるのメリットは大きいです。ですのでプロトタイプ自体を否定はしません。プロジェクトの初期段階では有効なツールの一つです。

しかし、それにしたって全ページのカンプをつくるワークフローをどうにかしたかった現場の皆さんが、気づけばプロトタイプのために工数倍になっていたり、下手に動くので実装コストを考えないデザイナーの夢のキャンバスになってしまっていたり…。結局こんな悲しみだけが広がって、業務をおしつぶすのだ…（by シャア総帥）


## 僕が望むプロトタイピングツールの要件

改めて要件をまとめてみましょう。もしすでにこれをカバーしてあまりある素晴らしきツールがあるなら教えてほしいです。

- **デザインを実機レベルで確認したい**
- **実際の画面遷移が確認したい**
- **クリッカブルベースでは対応できないレイアウトの実現**
- **インタラクティブな部分を想定したい**
- **コンポーネントを意識したい**
- **部分改修にもプロトタイピングツールが使いたい**
- **ゆくゆくはStab Apiと絡めて条件分岐したい**
- **gitで管理したい**

---

## もう、自分でそれっぽいの作るしか…

そこで目を付けたのが**[Vue.js](http://vuejs.org)**

<img src="https://qiita-image-store.s3.amazonaws.com/0/47955/9a6f7ba3-90be-c616-9272-92ca9bad1362.png" width="20%" />

Vue.jsは軽量なMVVMライブラリ。データバインディングをお手軽に実装できるのと、

- AngularやBackboneに比べて学習コストが圧倒的に低い。
- [Browserify](http://browserify.org/)との連携で[Vueify](https://github.com/vuejs/vueify)を使ってReadbilityの高いコンポーネントがつくれる。
    - CSS/Script/Htmlをコンポーネントにまとめて書く事ができる。
- v-transitionのDirectiveを使うことでUIのインタラクションも実装しやすい。
- ちなみにReact.jsでも良い。けど、render()のあたりがデザイナーにはとっつきにくそうなのでVue.js

## 今回やろうとしていること

- gulpでやる。
- 画像でつくったコンポーネントを置いてみる。
- ~~エラー処理してみる。~~
    - 時間がないのでまたの機会に


## とりあえず基本セット

[今回のリポジトリ](https://github.com/tyshgc/vue-prototyping)

```
$ sudo npm install && bower install
$ gulp
```

※Node.jsとか入れといてください。入れ方はググろう。


#### **使用するもの**

- **Jade** => Html Template Engine
- **Stylus** => Meta Css for Original Css
- **Vueify** => Component


#### **1. ディレクトリの準備**

- **src** => Editable Directory
    - **design** => PSD etc & Assets
    - **lib** => bower files
    - **scripts**
        - **vue** => Vueify Components
    - **jade**
        - **mixins** => jade mixin
        - **components** => jade components
    - **styles**
        - **stylus**
            - **components** => stylus components
            - **mixins** => stylus mixins
            - **extends** => stylus extends
            - **commons** => stylus commons & variables
    - **images**
        - **components** => component images
        - **fonts**
        - **sprites** => sprite image parts
        - **samples**
- **dest** => builded

## たのしいプロトタイピングの時間だ

今回はこんな感じ。超テキトー。

- ポイントはPositon Fixedを想定しているHeaderからおじさんがハミ出している。
- Material DesignぽいFloating Button。

<img src="https://qiita-image-store.s3.amazonaws.com/0/47955/e303fed3-e2b1-7068-cb29-9436b18f18ce.png" width="30%" />

因に、固定ヘッダーやMaterial DesignのようなFloating Buttonなんかをプロトタイピングツールで実現すると、矩形でしか固定部分を設定できないので、こんな残念な画面になります。ほんとはおじさんがはみ出しているのに。。

<img src="https://qiita-image-store.s3.amazonaws.com/0/47955/b2ae5429-7303-c67c-01c4-111fdaab3a09.png" width="30%" />


## 構成

- header=> position.fixed
    - おじさんの画像をheaderからはみ出して表示させる
- main.view
- Material Design ぽい Floating Buttonを置く

## 手順

#### **1. デザインつくる**

#### **2. コンポーネントごとにレイヤーでわけると良い**

#### **3. Photoshopならレイヤーグループにhoge.pngとかで適当に画像として分けたいところに名前をつける。**
- 今回なら
    - header.png
    - main_background.png
    - main_text.png
    - floating-button.png
    - ojisan.png

<img src="https://qiita-image-store.s3.amazonaws.com/0/47955/bbbe9168-c3f1-e813-27c9-0bbc41fa3537.png" width="50%" />


##### **4. src/design/assetsに上のファイルを置く**

Photoshopならアセット抽出で一発。

##### **5. コンポーネント毎にvueコンポーネントファイルを作成する**

```vue:onisan.vue
<style lang="stylus">
.ojisan
  background-image url(/images/ojisan.png)
  background-repeat no-repeat
  background-size cover
  position fixed
  z-index 999
  top 110px
  width 100px
  height 100px
  left 50%
  margin-left -50px
</style>

<template lang="jade">
.ojisan
</template>

<script>
module.exports = {}
</script>
```
- \<style>（主に位置と深度）などを書いていく。今回はStylusを使った。
- \<template>にhtmlを書いていく。画像なんでhtmlとか楽勝でしょ。今回はJadeを使った。
- \<script>にmodule.exports={};をいれる。とくにバインディングしなければこれでよし。
- バインディングするときはこんな感じ

```vue:main.vue

<style lang="stylus">
.main-view
  padding-top 200px
  height 1000px
  position relative
  background-image url(/images/main_background.png)
  background-size cover
  margin 0 auto
  width 100%
  
  .center
    text-align center
    position relative
    padding-top 20%
    
    img[layout_size="2x"]
      width 50%
      margin 0 auto
  .data-bind
    color #fff
</style>
<template lang="jade">
main.main-view
  p.center
    img(src="/images/main_text.png" layout_size="2x")
  .data-bind {{texts}}
</template>

<script>
module.exports = {
  data: function(){
    return {
      texts: 'でーたーばいんどー'
    };
  }
};
</script>

```

##### **9. app.jsの``new Vue({})``にcomponentsというオブジェクトがあるので、そこに適当に名前をつけていく**

```js:app.js

var Vue  = require("vue");

App = module.exports = new Vue({
  
  el: '#app',
  components: {
    'vue-header'  : require('./vue/header.vue'),
    'vue-main'    : require('./vue/main.vue'),
    'vue-ojisan'  : require('./vue/ojisan.vue'),
    'vue-floating-button'  : require('./vue/floating-button.vue')
  },
  
  data:{
    todo: []
  },
  
  created: function(){
    // なんかVueが生成されたときにしたかったらここ
  },
  
  methods: {
    // なんか処理いれたかったらここ
  }
  
});

```


## で、localhost:8000にアクセスすると…

おお！

<img src="https://qiita-image-store.s3.amazonaws.com/0/47955/7460eeda-be8d-02ae-7122-c7b1b4e4b7e6.png" width="50%" />

ちゃんとおじさんがはみだしているだろう？

<img src="https://qiita-image-store.s3.amazonaws.com/0/47955/1dd84882-cf8f-ab45-dbeb-c0e34ec46b41.png" width="50%" />


# 最後に

おじさんの画像を変えたかったら、src/design/assets/ojisan.pngをいじくれば変更できる。
おじさんにアニメーションをいれるStylusのmixinでもつくっておけば、アニメーションもいれれるだろうし、おじさんをタップしておじさんのscaleを2倍にすることも可能だろう。そうやっておじさんは可能性の獣になる。

ちなみに、別にstylusだったりjadeである必要もないです。

```vue:ojisan_kai.vue
<style>
.ojisan{
  background-image:url(/images/ojisan.png);
  background-repeat:no-repeat;
  ・
  ・
  ・
  margin-left:-50px;
</style>

<template>
<div class="ojisan"></div>
</template>

<script>
module.exports = {}
</script>
```


# 所感

これはあくまでデザインを各画面・ステートごとにつくる時間考えたらUIデザイナーもJavascriptのジャの字くらいのコード書いてしまえば早いんじゃね？的なものなので、実用性があるかどうかは各々判断してください。

よって、ケースによっては既存のプロトタイピングツールの方がいいという場合もあります。つまり、どれもこれもツールであってそれが本質でもゴールでもない。云いたいことはそれだったりします。