Vue.jsでつくってみた - マッスルエンジニアリング

この記事は [J2complexed Advent Calendar 2016](http://qiita.com/advent-calendar/2016/j2complexed) の3日目です。

個人的な話なのですが、今日は誕生日ということで好き勝手なことを書かせてもらいます。
※ すみません、公開に間に合いませんでした！

# マッスルエンジニアリングはじめました
先日、拝読させていただいた記事にとても感銘を受けました。

[マッスルエンジニアリングの提唱](http://qiita.com/masahixixi/items/0b9ecc00e26afd8015c1)

そうだったんですね！変数名がイケてなかったり、納品ファイルに漏れがあったりするのは筋肉が足りてなかったんですね！プロテイン飲まなくっちゃ！

## プロテインは奥が深い
みなさんはプロテイン、飲んでますか？飲んでなくても心配はいりません。プロテインって簡単に言うとタンパク質なので、普通に食事してても摂取できます。例えば、鶏むね肉が100gで22gくらい、牛乳なら200gで7gくらい摂取できます。安心ですね。

しかし、プロテインを摂取する効率的なタイミングがあります！

`特に運動後の30分以内を「ゴールデンタイム」といい、成長ホルモンが最も活発に分泌されるので、ダメージを受けた筋肉の修復に最も効果的であるといわれています。`
[なんとなく飲んでいませんか？プロテインの飲み方～トレーニング後～](http://sports-crowd.net/detail.php?no=3230)

ゴールデンタイム！

しかも、人間の体は１度に摂取できる限界量が決まっているのです！

`1回の限界摂取量＝体重×0.7g`
[プロテインの摂取方法！1回の限界摂取量は体重1kgあたり0.7g](http://www.futoritai.com/cat4/post_19.html)

トレーニング後に必要なプロテインの摂取量を知るためのwebページを用意しました。

# vue.jsであれこれ
最近お気に入りのvue.jsで作っていきます。
まず、vue-cliをインストールします。githubにインストール方法が書いてありますので、そのままです。
※ node.jsのバージョンは4か６で、Gitが必要です

[vue-cli](https://github.com/vuejs/vue-cli)

```bash
$ npm install -g vue-cli
```
無事、インストールできたら次はテンプレートを作成します。

やっぱり使い方も書いてある通りにやります。
`$ vue init <template-name> <project-name>`
ここまで簡単ですね。

webpackが好きなので、webpack-simpleを選びました。

```bash
$ vue init webpack-simple vue-muscle
```
To get started って始め方を教えてくれているので、その通りにコマンド入力をして確認してください。

```bash
$ cd vue-muscle
$ npm install
$ npm run dev
```

勢いよく用意されていたものがインストールされ、こんな感じでブラウザが起動したかと思います。

![スクリーンショット 2016-12-03 1.29.34.png](https://qiita-image-store.s3.amazonaws.com/0/109382/3f573496-084d-464d-8f7e-ff47e50e8d14.png)

これで、準備は完了です。あとは、いつもどおり作ります。
解説なしですみませんが、コードを晒しておきます。

```app.vue
<template>
  <div id="app">
    <h1 class="title">レッツ！ プロテイン！</h1>
    <div>
      <input class="yourWeight"
        type="text"
        :value="yourWeight"
        placeholder="edit me"
        @input="calcProtein"><span>kg</span>
    <div>
    <p class="balloon">{{ message }}</p>
    <p class="image"><img :src="image" /></p>
  </div>
</template>

<script>
export default {
  name: 'app',
  data () {
    return {
      message: ``,
      image: `./dist/muscle1.svg`,
      yourWeight: ''
    }
  },
  computed: {
    message: function () {
      const value = this.yourWeight && this.yourWeight.trim()
      if (!value) {
        this.image = `./dist/muscle1.svg`
        return `体重を入力してほしい`
      } else if(!isFinite(value)) {
        this.image = `./dist/muscle2.svg`
        return `そこは数字で入れて欲しい`
      } else if(isFinite(value)) {
        const result = Math.floor(value * 0.7 * 10) / 10
        this.image = `./dist/muscle4.svg`
        return `君に必要なプロテインは${result}グラムだ！`
      }
    }
  },
  methods: {
    calcProtein: _.debounce(function (e) {
      this.yourWeight = e.target.value
    }, 300)
  }
}
</script>

<style>
html, body {
  opacity: 1;
}
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.title {
  font-weight: bold;
  font-size: 8vw;
}
input[type="text"] {
  outline: none;
  border: 1px solid #aaa;
  transition: all .3s;
  font-size: 16px;
  padding: 5px;
  margin: 10px 5px 10px 0;
}
input[type="text"]:focus {
  box-shadow: 0 0 7px #1abc9c;
  border: 1px solid #1abc9c;
}
.image {
  width: 40vw;
  margin: 0 auto;
}
.balloon {
  position: relative;
  display: inline-block;
  padding: 0 15px;
  width: auto;
  min-width: 115px;
  height: 70px;
  color: #F6F6F6;
  line-height: 70px;
  text-align: center;
  font-weight: bold;
  background: #19283C;
  border-radius: 60%;
}
.balloon:before {
  content: "";
  position: absolute;
  bottom: -10px; left: 20px;
  margin-left: 0;
  display: block;
  width: 30px;
  height: 30px;
  background: #19283C;
  border-radius: 0 30px 0 30px;
  z-index: -1;
}
.balloon:after {
  content: "";
  position: absolute;
  bottom: -5px; left: 30px;
  margin-left: 0;
  display: block;
  width: 30px;
  height: 30px;
  background: #FFF;
  border-radius: 0 30px 0 30px;
  z-index: -1;
  transform: rotate(30deg);
}
</style>
```
で、できたのがコレ。
[レッツ！プロテイン！](https://lets-protein.herokuapp.com/)
![スクリーンショット 2016-12-05 3.09.30.png](https://qiita-image-store.s3.amazonaws.com/0/109382/a5064324-4b63-0a72-7c27-55abc491d951.png)

すばらしい・・・！イラストはこちらから頂きました。ありがとうございます！
[筋肉ムキムキのマッチョなボディビルダー ｜  シルエットデザイン](http://kage-design.com/wp/?p=1593)

## サーバサイドレンダリングする
せっかくなので、SEOに強いと言われているサーバサイドレンダリングにしてプロテインを布教しましょう！
サーバサイドレンダリングするために必要なプラグインをインストールします。

```bash
$ npm install vue-server-renderer express
```

あとは、公式に載っているserver.jsの書き方を参考（丸パクリ）にします。
（微妙にindex.htmlも変更してます）
[サーバサイドレンダリング](https://jp.vuejs.org/v2/guide/ssr.html)

# Herokuで世界に公開
ここまで来れば、あとは公開して、みんなにも利用していただこうと思います。
Herokuのダッシュボードから Creat new app でアプリを作ります。そうすると、大体のコマンドは書いてあるので、そのままですね。
書いてないとすれば、[Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli)をインストールしてから、ログインするということでしょうか。

```bash
$ heroku login
$ heroku git:clone -a lets-protein
$ cd lets-protein
$ git add .
$ git commit -am "make it better"
$ git push heroku master
・・・
remote: Verifying deploy.... done.
To https://git.heroku.com/lets-protein.git
 * [new branch]      master -> master
```
まとめるとこんな感じです。

# まとめ
体調を崩し、書き上げることができず、後半は雑になりました。健康は大切ですね。
そして、筋肉も大切です！
レッツ！プロテイン！