vueとvuexを使ってみた感想

最近vue.jsを使っている. 今日のは感想なんで,解決策とか対処法は一切ない.ただだらだらと感想が並ぶだけである.

今までずっとReactばかりだったんだけど,書いてみると普通にかける.Reactからvueに転身するのはハードル低い感じがした.

ただ,やっぱり状態管理はしたいなーと思って最初からvuexを入れたんだ.

嬉しかったこと

非同期処理は楽

redux-thunkとかredux-sageのような別のライブラリに巻き込まれることなく,actionsとmutatonsが書ければ,非同期処理もラクラクできる.

この点は圧倒的にvuexの方が楽だった.

算出プロパティは良い

vueのcomputedというやつだけど,こいつはなかなか良い.

依存関係に基づいてキャッシュされるので,computed内で,vuexのstoreを参照していれば,storeの更新に伴ってキャッシュがクリアされ再計算され,必要であれば再描画される. vuexのstoreから値を取るときに,ここでいろんなことを挟み込めるので,とても便利.

単一ファイルコンポーネントは扱いやすい

コンポーネントのファイルがひとつにまとまっているのは非常に良い.

まぁ,vuexを入れると,vuexの状態管理がコンポーネントファイル外に出るのだが.

styleをコンポーネントファイルに書けるのは最高だ. Reactの時に感じていた,「このコンポーネントにだけこのcssを当てたいから,頑張ってコンポーネント名をクラスに埋め込むか」とか「好きじゃないけどcss modules使うか」,みたいなことを考えなくて良い. scoped は素晴らしい.

ただ,一つのファイルに,html, js, cssの文法が混ざって出てくるのでエディタの設定は大変だろう.

emacsを使うなら,vue-mode はかなりおすすめだった.

github.com

mmm-modeで1ファイル内にありながら言語ごとに切り替えてくれる.

なれるとjsxよりは書きやすいよね

本当にこれは慣れだと思う. 最初,vue.jsのtemplateを見た時に,

  • 「まじかー,v-ifとか新しい記法生み出すのか」
  • 「まじかー,しかもv-ifの中身,文字列で記述するんか.シンタックスハイライトできなそうだし,エラーに気付きにくそう」

と思った.

jsxは本当にピュアなjavascript演算子ばかり出てくる代わりに,if文すら書けないけどな.

なれると,まぁjsxよりは書きやすいかもしれないって思えてくる.

つらいところ

vuexで状態管理しながらフォームを作るの難しい

www.slideshare.net

つまりはこういう問題なんだけど.

フォームの扱い · Vuex

公式では双方向算出もおすすめしている.が,mutations を書くのも,getter, setter 書くのもだるいよねっていう話.

結局俺も納得はしていない.

qiita.com

フォームの値をvuexで管理しないという手もあるのだが,それをやってしまうとデバッグしにくい. というのと,例えば,画像を非同期アップロードしてその結果をフィールドに埋めてPOSTしたい,みたいな要求が出てきた時,画像の非同期アップロードと結果格納も全てコンポーネント側で持たないといけない.

そうなるとvuexを使っている意味をあまり感じなくなってくる.

それなら,そもそもフォームに関してはvuex一切使わなくていいじゃない.

Redux Formってすごかった

この点,React ReduxではRedux Formという解決策がある.

こういう話を聞いているとRedux Formってすごく便利だなーと改めて認識する.

Redux Formはフォームの値をReduxのstoreで管理しつつ,それを全てRedux Form内で隠蔽してくれる.だから,フォームを追加する際に,俺がいちいちreducerにメソッドを追加したり,actionを新たに作ったりする必要がない. 基本的にコンポーネントにRedux Formに沿った記述をすれば,その中身はRedux Form側で管理してくれる.

vuexもこういうのがあったらいいのに.

routerへのアクセスがめんどくさい

vue-routerも使っている.

例えば,

/hoge というURLにPOSTし,正常にPOSTが成功したら / にリダイレクトしたいとしよう. これをvuexのactionsで書いていると,routerにアクセスできなくて困る.

vuex内では,vueコンポーネントと違って this.$router でrouterにアクセスできない.

github.com

というのもあるのだが,重要なことで, store.state.route is immutableとある. そう,URLパラメータを取得するようなことはできるが,リダイレクトのためにURLを書き換えることは出来ない.

仕方ないので,こうやるしかない.

github.com

わりかし好きなのは,コンポーネントのメソッドで,

logInUser () {
  this.$store.dispatch('logInUser', this.user).then(() => {
    this.$router.push({'path': '/app'})
   }).catch((err) => {
    console.log(err)
   })
}

のパターンだけど,これだと,通信結果を使うことが出来ない.

たとえば,

/items にPOSTして,itemのidが帰ってくるとしよう.で,POST成功後に /items/:id にリダイレクトしたい場合には,これを使うことは出来ない.

そういう場合は,vuex側でやっぱりなんとかするしかない.

import router from '../router'

// ...

createItem ({ commit }, item) {
  axios.post('/items`, item).then((res) => {
    router.push(`/items/${res.data.item.id}`)
  })
}

まとめ

postd.cc

ここに書いてあるほどの感動は得なかった.

確かにReduxみたいに,action, reducerをそれぞれ書かなきゃいけないめんどくささはなくなったけど,そういう気持ちはvuexとフォームの話で相殺された気がする.

そもそも俺はReact Reduxをやっていたので,学習コスト面で躓くことはなかった. まっさらな状態から始めたら,まぁvueやvuexの方が扱いやすいかもね,くらい.

Reactのjsxが嫌という話もよくわかるし,このへんは好みで決めたらいいんじゃないかなーと思う.

ただ,最近国内ではvue.jsへの関心が高いような気がする(気がするだけ,観測範囲の問題かも)ので,vueの不便だと思う点も改善されていくかもしれない.