Slide 1

Slide 1 text

Replace View of Backbone.js with Vue.js Vue.js Tokyo v-meetup #8 2018/08/28
 @_tanakaworld

Slide 2

Slide 2 text

About Me Yutaro Tanaka GitHub: tanakaworld
 Twitter: @_tanakaworld Software Engineer / Merpay, Inc.
 Vue.js / Nuxt / TypeScript
 
 Ruby / Rails / Python / Docker / AWS

Slide 3

Slide 3 text

履履歴書の Web 管理理+共有サービス開発してます
 Vue.js でのフロントエンドリニューアルを検討中
 
 リリース: Tech Crunch (tcrn.ch/2wbmfcq) https://proff.io PR

Slide 4

Slide 4 text

突然ですが

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

Backbone.js
 飽きていた

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

※ 仮の「Mind Map」 
 SPA アプリケーションを題材に
 説明します

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

• Backbone.js SPA • JointJS • Diagram 系の UI をつくれる • UI パーツが Backbone.Model と対応 • 有償版の Rappid で⾼高機能な GUI を実現
 https://www.jointjs.com/ とあるプロジェクト

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

( Demo )

Slide 18

Slide 18 text

( Demo ) GUI Editor Property Editor Demo

Slide 19

Slide 19 text

UI リニューアル

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

複雑な UI

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

Vue.js を採⽤用 ! !

Slide 27

Slide 27 text

完成 イメージ GUI Editor Property Editor

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

•既存構成はそのまま • Backbone.Router • Backbone.Model • Backbone.View (ページの表示) • JointJS (GUI Editor) • gulp / Browserify / babel •追加スタック • vueify (Browserifyで.vueファイルをコンパイル) • Vue • Vuex • 3rd party component
 ※ Vue Router は使わない フルリプレイスしたい気持ちをグッとこらえる

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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: `
` }); } ••• }

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

Vue Component の任意イベントで Action を dispatch 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(); } }, •••

Slide 38

Slide 38 text

4. jQuery + Vue Component

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

Demo

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

リリースは完了了

Slide 43

Slide 43 text

まとめ

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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/

Slide 48

Slide 48 text

Thanks Vue.js !!

Slide 49

Slide 49 text

Thanks !!