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

Replace View of Backbone with Vue

Replace View of Backbone with Vue

tanakaworld

August 28, 2018
Tweet

More Decks by tanakaworld

Other Decks in Technology

Transcript

  1. About Me Yutaro Tanaka GitHub: tanakaworld
 Twitter: @_tanakaworld Software Engineer

    / Merpay, Inc.
 Vue.js / Nuxt / TypeScript
 
 Ruby / Rails / Python / Docker / AWS
  2. • Backbone.js SPA • JointJS • Diagram 系の UI をつくれる

    • UI パーツが Backbone.Model と対応 • 有償版の Rappid で⾼高機能な GUI を実現
 https://www.jointjs.com/ とあるプロジェクト
  3. ⼤大幅にリニューアル •タブ UI で表示切り替え •⼦子 Item (Form) の追加・削除 •Input /

    Button / Dropdown Select / Radio •WYSIWYG Editor •Dropdown 要素の CRUD •⼊入⼒力力状態によって表示を動的に切り替え •インタラクティブなバリデーション •DBデータ構造変更更
 
 etc…
  4. • Vue.js は、より柔軟で⾃自⼰己を主張しな いライブラリ • Vue では⾃自分の好みのやり⽅方でアプリ を構築できる • 本格的な

    SPA を作成せずとも、イン ターフェイス・レイヤーとしてページ 内に軽度の機能実装を実現できる v1 「他のフレームワークとの⽐比較」より抜粋
 https://v1-jp.vuejs.org/guide/comparison.html
  5. •既存構成はそのまま • Backbone.Router • Backbone.Model • Backbone.View (ページの表示) • JointJS

    (GUI Editor) • gulp / Browserify / babel •追加スタック • vueify (Browserifyで.vueファイルをコンパイル) • Vue • Vuex • 3rd party component
 ※ Vue Router は使わない フルリプレイスしたい気持ちをグッとこらえる
  6. 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>` }); } ••• }
  7. export default class NodeEditor { ••• render(model) { store.commit(MUTATIONS.setModel, {model});

    this.vm.showEditor(); } close() { store.commit(MUTATIONS.clearModel); this.vm.hideEditor(); } } データのやりとりはインスタンスメソッド経由のみ
  8. 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) }); } }
  9. 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(); } }, •••
  10. • Backbone.js では jQuery 依存のライブ ラリを使っていることが多い • Vue Component 内では

    Vue のライブ ラリを使いたい • しかし完全対応していないケースも • 例例)At.js Vue Component 内で jQuery を使う
  11. 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 は検知しない • 変更更を伝える処理理を記述
  12. Backbone.js + Vue.js 導⼊入結果 • 既存ライブラリに⼲干渉しなかった • ⼩小さく部分的に始められる • UI

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

    ライフサイクル • jQuery の DOM 変更更は Vue.js のライフサイクル外 • 混ぜるな危険 • 境界線は明確に • 結局カオス化する
  14. 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/