運用中のシステムへのVue.jsを導入する際のあれこれ
背景
JQueryで頑張るのが辛くなってきたので、
フロントエンドにもFW入れたくなってきた。
下記の点を比較し、最終的にVue.jsを導入することにした。
- 学習コストの低さ
- 部分的な導入が可能
- FWとしての将来性
前提条件
- 運用中のシステム
- rails4.1系
- それなりの大きさのプロジェクト。しかもエンジニア一人か二人しかいないので、いきなり全取っ替えとか無理。
- npm未導入
- coffeescript使ってる
- IE9以上対応
- 非エンジニアも触るので、運用/開発の際の手間は増やしたくない
- リリース時のステップ数増えるとか
- 開発時に修正結果反映するまでのステップ数ふえるとか
- 導入方法
- 改修する周りから少しずつ。
導入の際に気を付けたこと
- 今回はJSフレームワークの導入がメイン
- ミニマムで導入していく
- いきなり色んな事はしない
- 既存のものはなるべく流用
- componentでパーツ毎に分割する
使わないもの
- npm
- 悩んだが、gemから乗り換える運用コスト払ってまで導入するメリット見当たらず。
- 結局vueとaxios以外入れないので
- gulp
- I love Sprockets!!!
- browserify
- 既存でこれ使わない呼び出し方でやってたので、これも使わない(後述)
- vueify
- Railsのviewを流用。vueファイル導入コスト払ってまで乗り換えるメリット見つからず。
- ES2015
- 今回はVue.jsの導入がメイン。これも導入するとなると学習コスト増えすぎ。
- babel
- ES2015使わないからこれも同様
とか
使うもの
- coffeescript
- 慣れてるのでまだ変えない。
- Sprockets
- やっぱり便利。まだ抜けられない。
- gem 'vuejs-rails'
- gem 'axios-rails'
-
vue-resource
は引退で、axios
が公式推奨なんだって。
- gem 'es6-promise-rails'
- IEでpromise(axios)使えないって怒られた。その対応用。
導入事始め
ディレクトリ構成
.
├── app
│ ├── asset
│ │ ├── javascript
│ | | ├── ProjectA
│ | | | ├── FuncA
│ | | | | ├── a.js.coffee
│ | | | | :
│ | | | ├── FuncB
│ | | | :
│ | | ├── ProjectB
│ | | :
│ | | └── frontend # Vue関連jsはここにまとめる
│ | | ├── ProjectA
│ | | | ├── funcA.js.coffee # Vue.new
│ | | | :
│ | | ├── ProjectB
│ | | :
│ | | └── components # Vue.component
│ | | ├── ProjectA
│ | | | ├── FuncA
│ | | | | ├── componentA.js.coffee
│ | | | | ├── componentB.js.coffee
│ | | | | :
│ | | | ├── FuncB
│ | | | :
│ | | ├── ProjectB
│ | | :
│ │ ├── stylesheet # ここはvueで分けず共通
│ │ └── images
│ ├── view
│ | ├── ProjectA
│ | | ├── FuncA
│ | | | ├── a.html.erb # ここで対象となるvueのpartialをrender
│ | | | :
│ | | :
│ | ├── ProjectB
│ | :
│ │ └── vue_template #vueのテンプレートはこちら
│ | ├── ProjectA
│ | | ├── FuncA
│ | | | ├── componentA.html.erb
│ | | | ├── componentB.html.erb
│ | | | :
- rails4.1系
- それなりの大きさのプロジェクト。しかもエンジニア一人か二人しかいないので、いきなり全取っ替えとか無理。
- npm未導入
- coffeescript使ってる
- IE9以上対応
- 非エンジニアも触るので、運用/開発の際の手間は増やしたくない
- リリース時のステップ数増えるとか
- 開発時に修正結果反映するまでのステップ数ふえるとか
- 改修する周りから少しずつ。
- 今回はJSフレームワークの導入がメイン
- ミニマムで導入していく
- いきなり色んな事はしない
- 既存のものはなるべく流用
- componentでパーツ毎に分割する
使わないもの
- npm
- 悩んだが、gemから乗り換える運用コスト払ってまで導入するメリット見当たらず。
- 結局vueとaxios以外入れないので
- 悩んだが、gemから乗り換える運用コスト払ってまで導入するメリット見当たらず。
- gulp
- I love Sprockets!!!
- browserify
- 既存でこれ使わない呼び出し方でやってたので、これも使わない(後述)
- vueify
- Railsのviewを流用。vueファイル導入コスト払ってまで乗り換えるメリット見つからず。
- ES2015
- 今回はVue.jsの導入がメイン。これも導入するとなると学習コスト増えすぎ。
- babel
- ES2015使わないからこれも同様 とか
使うもの
- coffeescript
- 慣れてるのでまだ変えない。
- Sprockets
- やっぱり便利。まだ抜けられない。
- gem 'vuejs-rails'
- gem 'axios-rails'
-
vue-resource
は引退で、axios
が公式推奨なんだって。
-
- gem 'es6-promise-rails'
- IEでpromise(axios)使えないって怒られた。その対応用。
導入事始め
ディレクトリ構成
.
├── app
│ ├── asset
│ │ ├── javascript
│ | | ├── ProjectA
│ | | | ├── FuncA
│ | | | | ├── a.js.coffee
│ | | | | :
│ | | | ├── FuncB
│ | | | :
│ | | ├── ProjectB
│ | | :
│ | | └── frontend # Vue関連jsはここにまとめる
│ | | ├── ProjectA
│ | | | ├── funcA.js.coffee # Vue.new
│ | | | :
│ | | ├── ProjectB
│ | | :
│ | | └── components # Vue.component
│ | | ├── ProjectA
│ | | | ├── FuncA
│ | | | | ├── componentA.js.coffee
│ | | | | ├── componentB.js.coffee
│ | | | | :
│ | | | ├── FuncB
│ | | | :
│ | | ├── ProjectB
│ | | :
│ │ ├── stylesheet # ここはvueで分けず共通
│ │ └── images
│ ├── view
│ | ├── ProjectA
│ | | ├── FuncA
│ | | | ├── a.html.erb # ここで対象となるvueのpartialをrender
│ | | | :
│ | | :
│ | ├── ProjectB
│ | :
│ │ └── vue_template #vueのテンプレートはこちら
│ | ├── ProjectA
│ | | ├── FuncA
│ | | | ├── componentA.html.erb
│ | | | ├── componentB.html.erb
│ | | | :
.
├── app
│ ├── asset
│ │ ├── javascript
│ | | ├── ProjectA
│ | | | ├── FuncA
│ | | | | ├── a.js.coffee
│ | | | | :
│ | | | ├── FuncB
│ | | | :
│ | | ├── ProjectB
│ | | :
│ | | └── frontend # Vue関連jsはここにまとめる
│ | | ├── ProjectA
│ | | | ├── funcA.js.coffee # Vue.new
│ | | | :
│ | | ├── ProjectB
│ | | :
│ | | └── components # Vue.component
│ | | ├── ProjectA
│ | | | ├── FuncA
│ | | | | ├── componentA.js.coffee
│ | | | | ├── componentB.js.coffee
│ | | | | :
│ | | | ├── FuncB
│ | | | :
│ | | ├── ProjectB
│ | | :
│ │ ├── stylesheet # ここはvueで分けず共通
│ │ └── images
│ ├── view
│ | ├── ProjectA
│ | | ├── FuncA
│ | | | ├── a.html.erb # ここで対象となるvueのpartialをrender
│ | | | :
│ | | :
│ | ├── ProjectB
│ | :
│ │ └── vue_template #vueのテンプレートはこちら
│ | ├── ProjectA
│ | | ├── FuncA
│ | | | ├── componentA.html.erb
│ | | | ├── componentB.html.erb
│ | | | :
.vueファイルは使わない。(導入の手間省く)
vue関連のファイルはディレクトリでなるべくまとめる
宣言/呼出
機能毎にVueをnewし、必要なコンポーネントを適宜呼び出すよう実装した。
本当ななるべく広い範囲をelementとしてVue.newしたかったが、
後述の問題点等により、ひとまず機能単位とした。
(★どの範囲をelementとするのがベストか。要調査)
$ ->
class FuncAVue
constructor: (hub) ->
Vue.prototype.$http = axios
new Vue(
el: '#func_a'
data: {}
)
window.funcAVue = ->
hub = new Vue() # コンポーネント間イベント通信するため
componentAVue(hub) # コンポーネントはここで宣言
:
new FuncAVue(hub)
vueのnewとコンポーネントは上記のようにclassで管理して、
<script type="text/javascript">
$(function(){
funcAVue();
});
</script>
:
erbでメソッドを実行することで呼び出す。
ちなみにコンポーネントは、
$ ->
class ComponentAVue
constructor: (hub) ->
Vue.component('sample_component', {
template: '#sample_component_template'
data: ->
return {}
})
window.componentAVue = (hub) ->
new ComponentAVue(hub)
こんな感じ。
課題
handlebarsとの共存
handlebarsを利用しているのだが、こちらとデリミタが被ってしまっている。
new Vue(
delimiters: ['${', '}']
:
)
でvueのデリミタを変更することで共存が可能となるはずなのだが、
なぜだかできない。要調査。
まとめ
今回、既存システムにVueをミニマムで導入してみた。
コンポーネントは、1フォームフィールド単位、1submitボタン単位などで作ってみた。
本当は相互に絡まない単位でコンポーネント化したかったが、
どうしても絡んでしまうようになってしまったため、
イベントハブやaxiosは途中で導入する事となった。
その辺こそ試行錯誤する事となった部分でもあるため、
また今度書きたい。
また、まだ導入初期のため効果の実感としては薄いが、
jQueryでガリガリ場合分けしていた部分等は見通しがスッキリしたので、
メンテナンスはかなりやりやすくなった。気がする。
参考
Author And Source
この問題について(運用中のシステムへのVue.jsを導入する際のあれこれ), 我々は、より多くの情報をここで見つけました https://qiita.com/tashua314/items/85440d140043fe4d8d9f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .