Replace View of Backbone with Vue

851704b2aa97d2117dc89bf60a2cd272?s=47 tanakaworld
August 28, 2018

Replace View of Backbone with Vue

851704b2aa97d2117dc89bf60a2cd272?s=128

tanakaworld

August 28, 2018
Tweet

Transcript

  1. Replace View of Backbone.js with Vue.js Vue.js Tokyo v-meetup #8

    2018/08/28
 @_tanakaworld
  2. About Me Yutaro Tanaka GitHub: tanakaworld
 Twitter: @_tanakaworld Software Engineer

    / Merpay, Inc.
 Vue.js / Nuxt / TypeScript
 
 Ruby / Rails / Python / Docker / AWS
  3. 履履歴書の Web 管理理+共有サービス開発してます
 Vue.js でのフロントエンドリニューアルを検討中
 
 リリース: Tech Crunch (tcrn.ch/2wbmfcq)

    https://proff.io PR
  4. 突然ですが

  5. [Q] Backbone.js で
 SPA 開発したことある⽅方 ?

  6. Backbone.View ツラくありませんか?
 (2018 年年現在)

  7. データバインディング ツラい backbone.stickit (NYTimes 製),Rivets.js, etc...
 無理理⽮矢理理感

  8. UI の再利利⽤用が難しい Backbone.View に分割 → Template が空に JavaScript から個別にレンダリング
 ⾒見見通し悪い

  9. 3rd Party Module の枯渇 メンテされていない

  10. Backbone.js
 飽きていた

  11. Vue.js で開発したい !!!

  12. Backbone.js SPA の⼀一部を Vue.js で書いたら 幸せになった話 Vue.js Tokyo v-meetup #8

    2018/08/28
 @_tanakaworld
  13. ※ 仮の「Mind Map」 
 SPA アプリケーションを題材に
 説明します

  14. 〇〇 + Vue.js アーキテクチャ事例例

  15. • Backbone.js SPA • JointJS • Diagram 系の UI をつくれる

    • UI パーツが Backbone.Model と対応 • 有償版の Rappid で⾼高機能な GUI を実現
 https://www.jointjs.com/ とあるプロジェクト
  16. 構成 イメージ • D&D で要素を追加 • 線でつなげたり, 場所を移動できる • 要素を選択すると,

    詳細のプロパティ を編集できる GUI Editor Property Editor
  17. ( Demo )

  18. ( Demo ) GUI Editor Property Editor Demo

  19. UI リニューアル

  20. ⼤大幅にリニューアル •タブ UI で表示切り替え •⼦子 Item (Form) の追加・削除 •Input /

    Button / Dropdown Select / Radio •WYSIWYG Editor •Dropdown 要素の CRUD •⼊入⼒力力状態によって表示を動的に切り替え •インタラクティブなバリデーション •DBデータ構造変更更
 
 etc…
  21. 複雑な UI

  22. None
  23. Backbone.js で 実装できる⾃自信ない

  24. None
  25. • Vue.js は、より柔軟で⾃自⼰己を主張しな いライブラリ • Vue では⾃自分の好みのやり⽅方でアプリ を構築できる • 本格的な

    SPA を作成せずとも、イン ターフェイス・レイヤーとしてページ 内に軽度の機能実装を実現できる v1 「他のフレームワークとの⽐比較」より抜粋
 https://v1-jp.vuejs.org/guide/comparison.html
  26. Vue.js を採⽤用 ! !

  27. 完成 イメージ GUI Editor Property Editor

  28. ポイント 1. 使える資産はそのままに 2. Vue Component をラップするクラス 3. Store に

    Backbone.Model をもたせる 4. jQuery + Vue Component
  29. 1. 使える資産はそのままに

  30. •既存構成はそのまま • Backbone.Router • Backbone.Model • Backbone.View (ページの表示) • JointJS

    (GUI Editor) • gulp / Browserify / babel •追加スタック • vueify (Browserifyで.vueファイルをコンパイル) • Vue • Vuex • 3rd party component
 ※ Vue Router は使わない フルリプレイスしたい気持ちをグッとこらえる
  31. 2. Vue Component をラップするクラス

  32. this.nodeEditor = new NodeEditor({el: '.MindMap__NodeEditor'});

  33. export default class NodeEditor { constructor({el}) { this.vm = new

    Vue({ el, store, data: { show: false }, components: { App }, methods: { ...mapGetters([ GETTERS.getModel ]), showEditor() { this.show = false; this.$nextTick(() => { this.show = true; }); }, hideEditor() { this.show = false; } }, template: `<div v-if="show && getModel()"><App :id="getModel().get('id')" :title="getModel().get('title')" :color="getModel().get('color')" /></div>` }); } ••• }
  34. export default class NodeEditor { ••• render(model) { store.commit(MUTATIONS.setModel, {model});

    this.vm.showEditor(); } close() { store.commit(MUTATIONS.clearModel); this.vm.hideEditor(); } } データのやりとりはインスタンスメソッド経由のみ
  35. 3. Store に Backbone.Model を もたせる

  36. Action で Backbone.Model の処理理を使う export default new Vuex.Store({ state: {

    model: null }, ••• mutations: { [MUTATIONS.setModel](state, {model}) { state.model = model; }, [MUTATIONS.clearModel](state) { state.model = null; } }, actions: { [ACTIONS.SAVE_MODEL]: ({commit, dispatch, state}, {title, color}) => { state.model.save({title, color}); // PUT /models/:id が実⾏行行される }, [ACTIONS.DELETE_MODEL]: ({commit, dispatch, state}) => { state.model.destroy({ // DELTE /models/:id が実⾏行行される success: () => commit(MUTATIONS.clearModel) }); } }
  37. Vue Component の任意イベントで Action を dispatch <script> import {mapActions} from

    'vuex'; import {ACTIONS} from './store'; export default { ••• methods: { ...mapActions([ ACTIONS.SAVE_MODEL, ACTIONS.DELETE_MODEL ]), onBlurTitle() { this.SAVE_MODEL({ title: this.tmpTitle, color: this.tmpColor }); }, onClickDelete() { this.DELETE_MODEL(); } }, •••
  38. 4. jQuery + Vue Component

  39. • Backbone.js では jQuery 依存のライブ ラリを使っていることが多い • Vue Component 内では

    Vue のライブ ラリを使いたい • しかし完全対応していないケースも • 例例)At.js Vue Component 内で jQuery を使う
  40. Demo

  41. import 'at.js'; import 'at.js/dist/css/jquery.atwho.min.css'; import $ from 'jquery'; export default

    { ••• mounted() { const $el = $(this.$refs['WYSIWYG']); $el.atwho({ at: "@", •••, callbacks: { // jQuery による変更更を検知 beforeInsert: (value) => { setTimeout(() => { this.emitChange(); }, 300); return value; } } }); }, methods: { emitChange() { const $el = $(this.$refs['WYSIWYG']); this.$emit('input', $el.html()); } } jQuery による DOM 更更新は Vue Component のライフサイクル外 • mounted 内で, $refs を 使い DOM を取得 • jQuery による DOM 更更新 を Vue は検知しない • 変更更を伝える処理理を記述
  42. リリースは完了了

  43. まとめ

  44. ポイントおさらい 1. 使える資産はそのままに フルリプレイスしたい気持ちをグッとこらえる 2. Vue Component をラップするクラス データのやりとりはインスタンスメソッド経由のみ 3.

    Store に Backbone.Model をもたせる Action で Backbone.Model の処理理を使う 4. jQuery + Vue Component Vue Component 内で jQuery を使う
  45. Backbone.js + Vue.js 導⼊入結果 • 既存ライブラリに⼲干渉しなかった • ⼩小さく部分的に始められる • UI

    パーツの Component 化で効率アップ • UI パーツを毎に共通コンポーネントを実装 • UI の仕様変更更にも柔軟に対応できた • モデル・通信周りは Backbone.Model が やってくれて楽
  46. 注意したい点 • バンドルサイズ • 圧縮 + gzipして約 2.6 MB •

    ライフサイクル • jQuery の DOM 変更更は Vue.js のライフサイクル外 • 混ぜるな危険 • 境界線は明確に • 結局カオス化する
  47. Source Code • Mind Map
 stack: webpack/Backbone.js/Vue.js/Vuex/Express/Realm 
 https://github.com/tanakaworld/replace-view-of-backbone-with-vue •

    Vue.js と At.js を組み合わせる
 https://github.com/tanakaworld/vue-with-atjs
 https://blog.tanaka.world/vue-wysiwyg-editor-with-atjs/
  48. Thanks Vue.js !!

  49. Thanks !!