reactからvueにお引っ越ししてみる(前篇)

しばらくReactでアプリ書いていたけど、例のライセンスの件があったのでVue.jsでアプリを書いてみる
ちょうどつくり始めたreactのアプリがあったのでvueに置き換えるために調べたことや気になったことををまとめてみる

公式
https://jp.vuejs.org/index.html

# 動かしてみる
vue-cliでアプリの初期設定ファイル群を作ってくれる

```sh
npm install -g vue-cli
vue init webpack my-project
# プロンプトへ回答
cd my-project
npm install
npm run dev
```

試しに出力されたもの

```
.babelrc
.editconfig
.eslintignore
.eslintrc.js
.gitignore
.postcssrc.js
build/
config/
index.html
package.json
README.md
src/
static/
test/
```

プロンプトでtestをnoにしたらnpm run devで失敗した

# macVimの環境構築
自分はmacVimで書いているので必要なpluginを追加する
.vueファイルでjs/template/cssがまとめて記述されるので.vueのハイライトをできるようにする
これ入れた
https://github.com/posva/vim-vue

vim上でlintの結果も見たかったので
https://github.com/sekel/vim-vue-syntastic
を入れて下記を設定

```js
let g:syntastic_vue_checkers = ['eslint']
let local_eslint = finddir('node_modules', '.;') . '/.bin/eslint'
if matchstr(local_eslint, "^\/\\w") == ''
    let local_eslint = getcwd() . "/" . local_eslint
endif
if executable(local_eslint)
    let g:syntastic_vue_eslint_exec = local_eslint
endif
```

これでvueファイルを開いたときにmacVim上でlintエラーがみえるようになった

# vue-devtool
デバッグ用にvue-devtool入れる
https://github.com/vuejs/vue-devtools

# vue-router

reactだとreact-router相当

ネストされたルートや
https://router.vuejs.org/ja/essentials/nested-routes.html
トランジション
https://router.vuejs.org/ja/advanced/transitions.html
だいたいのことはできそう

# vuex

reactだとredux相当

https://jp.vuejs.org/v2/guide/state-management.html#React-開発者への情報

```
redux は実際に view レイヤの知識を持たないので、シンプルなバインディング を通して簡単に Vue とあわせて利用することができます。Vuex は、 自らが Vue のアプリケーション内にいることを知っている、という点で異なります。
```

アプリケーションへの依存の度合いが違いそう

## redux

reduxの３大原則

- Single source of truth. アプリの状態をもつStoreはただ1つ。
- state is read-only. 状態を変更するには必ずActionを発行しなければならない。
- Changes are made with pure functions. Actionにより状態をどう変更させるかはReducerが行なう。

### action
actionでtypeを定義してtypeをdispatchすることでstateが変更される

### reducer
pure functionとして副作用なく次の状態を変更する

### stateの取得
mapStateToPropsで任意のstateをpropsとしてcontainerで利用

## vuex

vuexの３大原則

- アプリケーションレベルの状態はストアに集約されます。
- 状態を変更する唯一の方法は、同期的に処理を行うミューテーションをコミットすることのみです。
- 非同期的なロジックはカプセル化されるべきであり、それはアクションによって構成されます。

### mutation
同期でなければならない
componentからmutationをcommitすることもできる
mutation-typeを持つ. reduxだとactionでtypeを定義していたがvueではmutation寄り
公式ではmutation-typeは単一ファイルにすることをおすすめしている

### action
actionはmutationをコミットする
actionは非同期処理を含むことができる

### getter
storeの状態を取得する仕組み
stateに何らかの処理を加えて値を返せる

### module
reduxにおけるreducerの分割に相当する部分をコンセプトとして機能化している
reduxではstateをimmutableに扱ってアプリケーションで一つのstateしか持たないが、
vueではmoduleとしてstoreを分割できるようにしている

### stateの取得
computed+getterで取得

## ディレクトリ構成

reduxでは

```
- actions
- reducers
- components
- containers
```

という構成を取るケースが多かった気がするが

vuexでは

```
store - modules - xxxx - actions.js, mutations.js
                - yyyy - actions.js, mutations.js
      - mutation-types.js
components
pages
```
という構成が多そう。store下にglobal actionとかを持たせるサンプルもあったがactionとmutationがでかくなるのはいやだから分割するのがよいかな

参考:
https://github.com/re-fort/vue-webpack-boilerplate/tree/master/src/store
https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart/store
https://github.com/petervmeijgaard/vue-2.0-boilerplate/tree/master/src/store
https://github.com/the6thm0nth/vue-2.x-boilerplate/tree/master/src/store

# component

## lifecycle
reactと似たようなタイミングはこんな感じか

### beforeMount
componentWillMount()

### mounted
vm.$nextTickがcomponentDidMount()のタイミングか

### beforeUpdate

componentWillUpdate()

### update
componentDidUpdate()

view全体まで待つ場合はvm.$nextTickを利用する

```js
updated: function () {
  this.$nextTick(function () {
    // ビュー全体が再レンダリングされた後にのみ実行されるコード
  })
}
```

### activated
生き続けたコンポーネントが活性化するとき呼ばれる
タイミングとしてはcomponentWillUpdate()が近いか

### deactivated
生存し続けたコンポーネントが非活性化されるとき呼ばれる
reactにはなかったと思う

### beforeDestroy
componentWillUnmount()

### destroy
ない


- shouldComponentUpdate()
  - 無いというか不要とのこと. 条件でrenderをコントロールすればよい
  - https://github.com/vuejs/vue/issues/4255
- componentWillReceiveProps()
  - こっちも同様に不要であろう


## stateless function
特に意識せずcomponentを作成する
reactと同じようにpropsもらってそれを表示するcomponentで良さそう

# 型
props validationは自前である
https://jp.vuejs.org/v2/guide/components.html#プロパティ検証

それ以外でやるのであればflowは使わないのでTypeScript

# UIライブラリ
reactではreact-bootstrapとかmaterial ui, onsenuiをメインに使ってた
vueでもonsenuiはある

Elementが人気ぽい
TransferとかStepとかがあるのがよい。前のプロジェクト自前で作ったよ。。。
カラーテーマもあるし、一通りのことはできそう
http://element.eleme.io/#/en-US/component/custom-theme