Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Replace View of Backbone with Vue

tanakaworld
August 28, 2018

Replace View of Backbone with Vue

tanakaworld

August 28, 2018
Tweet

More Decks by tanakaworld

Other Decks in Technology

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 !!