$30 off During Our Annual Pro Sale. View Details »

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

    View Slide

  2. About Me
    Yutaro Tanaka
    GitHub: tanakaworld

    Twitter: @_tanakaworld
    Software Engineer / Merpay, Inc.

    Vue.js / Nuxt / TypeScript


    Ruby / Rails / Python / Docker / AWS

    View Slide

  3. 履履歴書の Web 管理理+共有サービス開発してます

    Vue.js でのフロントエンドリニューアルを検討中


    リリース: Tech Crunch (tcrn.ch/2wbmfcq)
    https://proff.io
    PR

    View Slide

  4. 突然ですが

    View Slide

  5. [Q]
    Backbone.js で

    SPA 開発したことある⽅方 ?

    View Slide

  6. Backbone.View
    ツラくありませんか?

    (2018 年年現在)

    View Slide

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

    無理理⽮矢理理感

    View Slide

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

    ⾒見見通し悪い

    View Slide

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

    View Slide

  10. Backbone.js

    飽きていた

    View Slide

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

    View Slide

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

    @_tanakaworld

    View Slide

  13. ※ 仮の「Mind Map」 

    SPA アプリケーションを題材に

    説明します

    View Slide

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

    View Slide

  15. • Backbone.js SPA
    • JointJS
    • Diagram 系の UI をつくれる
    • UI パーツが Backbone.Model と対応
    • 有償版の Rappid で⾼高機能な GUI を実現

    https://www.jointjs.com/
    とあるプロジェクト

    View Slide

  16. 構成 イメージ
    • D&D で要素を追加
    • 線でつなげたり,
    場所を移動できる
    • 要素を選択すると,
    詳細のプロパティ
    を編集できる
    GUI Editor
    Property Editor

    View Slide

  17. ( Demo )

    View Slide

  18. ( Demo )
    GUI Editor Property Editor
    Demo

    View Slide

  19. UI リニューアル

    View Slide

  20. ⼤大幅にリニューアル
    •タブ UI で表示切り替え
    •⼦子 Item (Form) の追加・削除
    •Input / Button / Dropdown Select / Radio
    •WYSIWYG Editor
    •Dropdown 要素の CRUD
    •⼊入⼒力力状態によって表示を動的に切り替え
    •インタラクティブなバリデーション
    •DBデータ構造変更更


    etc…

    View Slide

  21. 複雑な UI

    View Slide

  22. View Slide

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

    View Slide

  24. View Slide

  25. • Vue.js は、より柔軟で⾃自⼰己を主張しな
    いライブラリ
    • Vue では⾃自分の好みのやり⽅方でアプリ
    を構築できる
    • 本格的な SPA を作成せずとも、イン
    ターフェイス・レイヤーとしてページ
    内に軽度の機能実装を実現できる
    v1 「他のフレームワークとの⽐比較」より抜粋

    https://v1-jp.vuejs.org/guide/comparison.html

    View Slide

  26. Vue.js を採⽤用 ! !

    View Slide

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

    View Slide

  28. ポイント
    1. 使える資産はそのままに
    2. Vue Component をラップするクラス
    3. Store に Backbone.Model をもたせる
    4. jQuery + Vue Component

    View Slide

  29. 1.
    使える資産はそのままに

    View Slide

  30. •既存構成はそのまま
    • Backbone.Router
    • Backbone.Model
    • Backbone.View (ページの表示)
    • JointJS (GUI Editor)
    • gulp / Browserify / babel
    •追加スタック
    • vueify (Browserifyで.vueファイルをコンパイル)
    • Vue
    • Vuex
    • 3rd party component

    ※ Vue Router は使わない
    フルリプレイスしたい気持ちをグッとこらえる

    View Slide

  31. 2.
    Vue Component
    をラップするクラス

    View Slide

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

    View Slide

  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: `:id="getModel().get('id')"
    :title="getModel().get('title')"
    :color="getModel().get('color')"
    />`
    });
    }
    •••
    }

    View Slide

  34. export default class NodeEditor {
    •••
    render(model) {
    store.commit(MUTATIONS.setModel, {model});
    this.vm.showEditor();
    }
    close() {
    store.commit(MUTATIONS.clearModel);
    this.vm.hideEditor();
    }
    }
    データのやりとりはインスタンスメソッド経由のみ

    View Slide

  35. 3.
    Store に Backbone.Model を
    もたせる

    View Slide

  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)
    });
    }
    }

    View Slide

  37. Vue Component の任意イベントで Action を dispatch
    <br/>import {mapActions} from 'vuex';<br/>import {ACTIONS} from './store';<br/>export default {<br/>•••<br/>methods: {<br/>...mapActions([<br/>ACTIONS.SAVE_MODEL,<br/>ACTIONS.DELETE_MODEL<br/>]),<br/>onBlurTitle() {<br/>this.SAVE_MODEL({<br/>title: this.tmpTitle,<br/>color: this.tmpColor<br/>});<br/>},<br/>onClickDelete() {<br/>this.DELETE_MODEL();<br/>}<br/>},<br/>•••<br/>

    View Slide

  38. 4.
    jQuery + Vue Component

    View Slide

  39. • Backbone.js では jQuery 依存のライブ
    ラリを使っていることが多い
    • Vue Component 内では Vue のライブ
    ラリを使いたい
    • しかし完全対応していないケースも
    • 例例)At.js
    Vue Component 内で jQuery を使う

    View Slide

  40. Demo

    View Slide

  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 は検知しない
    • 変更更を伝える処理理を記述

    View Slide

  42. リリースは完了了

    View Slide

  43. まとめ

    View Slide

  44. ポイントおさらい
    1. 使える資産はそのままに
    フルリプレイスしたい気持ちをグッとこらえる
    2. Vue Component をラップするクラス
    データのやりとりはインスタンスメソッド経由のみ
    3. Store に Backbone.Model をもたせる
    Action で Backbone.Model の処理理を使う
    4. jQuery + Vue Component
    Vue Component 内で jQuery を使う

    View Slide

  45. Backbone.js + Vue.js 導⼊入結果
    • 既存ライブラリに⼲干渉しなかった
    • ⼩小さく部分的に始められる
    • UI パーツの Component 化で効率アップ
    • UI パーツを毎に共通コンポーネントを実装
    • UI の仕様変更更にも柔軟に対応できた
    • モデル・通信周りは Backbone.Model が
    やってくれて楽

    View Slide

  46. 注意したい点
    • バンドルサイズ
    • 圧縮 + gzipして約 2.6 MB
    • ライフサイクル
    • jQuery の DOM 変更更は Vue.js のライフサイクル外
    • 混ぜるな危険
    • 境界線は明確に
    • 結局カオス化する

    View Slide

  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/

    View Slide

  48. Thanks Vue.js !!

    View Slide

  49. Thanks !!

    View Slide