Slide 1

Slide 1 text

RiotでSPAなう! 2016/08/04 Meguro.es #5 @mizuki_r

Slide 2

Slide 2 text

@mizuki_r (株)モバイルファクトリー フロントエンドエンジニア JS, Perl Angular, Vue, Riot “HTMLは情報設計言語です!” 2

Slide 3

Slide 3 text

本日のお題 3

Slide 4

Slide 4 text

RiotJSで SinglePageAppを 作る

Slide 5

Slide 5 text

ーー過程で起きた事例の紹介

Slide 6

Slide 6 text

絶賛制作進行中です! あしからず

Slide 7

Slide 7 text

構成 7

Slide 8

Slide 8 text

構成 • Webpack • Riot • syntagme • jQuery + jQuery-Plugin 8

Slide 9

Slide 9 text

というわけで、 事例の紹介 をします。 9

Slide 10

Slide 10 text

事例1. ルーティング 10

Slide 11

Slide 11 text

事例1. ルーティング • URLରͯ͠೚ҙͷॲཧΛ࣮ߦ͢Δ • riot͸ϓϦΠϯͰRouterΛఏڙ͍ͯ͠Δ • http://riotjs.com/ja/api/route/

Slide 12

Slide 12 text

本当にそれで十分?

Slide 13

Slide 13 text

足りなかったので 魔改造した

Slide 14

Slide 14 text

魔改造1. コンポーネントのマウント

Slide 15

Slide 15 text

魔改造1. コンポーネントのマウント • riot.router͸URLͷมߋ࣌ʹίʔϧόοΫΛ࣮ ߦ • ReactRouterΈ͍ͨʹComponentΛϧʔςΟϯ ά͢ΔΘ͚Ͱ͸ͳ͍

Slide 16

Slide 16 text

魔改造1. コンポーネントのマウント this.routes = [ { path: '/', component: 'home', param_keys: [ 'pickup_list', 'popular_list' ] }, { path: '/user/:user_id', component: 'user', param_keys: [ 'user' ] } { path: '/user..', component: 'user-list', param_keys: ['user_list'] }, ] ͜Μͳײ͡Ͱ࢖͑ΔΑ͏ʹϥοϓ

Slide 17

Slide 17 text

魔改造2. パラメータマッチングの拡張

Slide 18

Slide 18 text

魔改造2. パラメータマッチングの拡張 • riot.route͸ΫΤϦύϥϝʔλ͔͠ѻ͑ͳ͍ • /path/:id/toΛύʔεͯ͠{id: 1234}ΛऔΕΔΑ͏ ʹվ଄

Slide 19

Slide 19 text

魔改造2. パラメータマッチングの拡張 function secondParser (path, filter) { let keys = [] let format = filter .replace(/\*/g, '([^/?#]+?)') .replace(/\.\./, '.*') .replace(/:([^/?#]+)/g, (pattern, key) => { keys.push(key); return '([^/?#]+?)'}) let re = new RegExp('^' + format + '$') let args = path.match(re) if (args) { args = args.slice(1) let params = _.reduce(keys, (prev, key) => { prev[key] = args.shift(); return prev }, {}) args.unshift(params) return args } } riot.route.parser(null, secondParser) ͜͏͍͏ͷΛఆٛͯ͋͛͠Δͱ…

Slide 20

Slide 20 text

魔改造2. パラメータマッチングの拡張 औΕΔΑ͏ʹͳΔʂ riot.route('/path/:id/to', function (args) { console.log(args.id) })

Slide 21

Slide 21 text

魔改造3. popStateで更新する

Slide 22

Slide 22 text

魔改造3. popStateで更新する • riot.route͸popStateͷΠϕϯτΛ؂ࢹ͍ͯ͠ ͳ͍ • ͳͷͰࣗલͰ؂ࢹ͢Δ

Slide 23

Slide 23 text

魔改造3. popStateで更新する window.addEventListener('popstate', () => { riot.route.exec() }) ※riot.route.exec͸2.3͔ΒdeprecatedͰ͢

Slide 24

Slide 24 text

魔改造4. マウント時にルーティング

Slide 25

Slide 25 text

魔改造4. マウント時にルーティング • URLͷมߋΛݕ஌ͯ͠ίʔϧόοΫΛ࣮ߦ • Ϛ΢ϯτ࣌ʹ͸URL͸͢Ͱʹܾఆ͍ͯ͠Δͷ Ͱ࣮ߦͯ͘͠Εͳ͍(´ʀТʀʆ) • ͳͷͰɺखಈͰୟ͘

Slide 26

Slide 26 text

魔改造4. マウント時にルーティング this.on('mount', function () { riot.route.exec() }) ※riot.route.exec͸2.3͔ΒdeprecatedͰ͢

Slide 27

Slide 27 text

Q. 公開しないんですか?

Slide 28

Slide 28 text

Q. 公開しないんですか? • ͱΓ͋͑ͣಈ͘΋ͷΛ࡞ͬͨϨϕϧͳΜͩ • ͜Ε͔Βௐ੔͢Δ • Ͱ͖Δஈ֊ʹͳͬͨΒ͓ͦΒ͘ ެ։͢Δʂ

Slide 29

Slide 29 text

事例2. カルーセル 29

Slide 30

Slide 30 text

事例2. カルーセル • ԣʹεϥΠυ͢ΔόφʔͷΞϨ • θϩ͔Β࡞Δͷ͸ΊΜͲ͍͘͞

Slide 31

Slide 31 text

jQueryPluginで いいのがありますよ!!

Slide 32

Slide 32 text

http://kenwheeler.github.io/slick/

Slide 33

Slide 33 text

事例2. カルーセル $(this.root).slick() ཁૉΛjQueryʹ͘Θͤͯυʔϯ

Slide 34

Slide 34 text

事例2. カルーセル • jQuery·͡ศར • ͨͩɺWebpackͰjQuery + pluginΛ͍͍ײ͡ ʹѻ͏ज़Λݟ͚ͭΒΕͯͳ͍

Slide 35

Slide 35 text

事例2. アニメーション 35

Slide 36

Slide 36 text

事例2. アニメーション • ཁૉΛදࣔɾඇදࣔͨ͠ͱ͖ʹΞχϝʔγϣ ϯΛ͔͚͍ͨ • ng-enter, ng-leaveΈ͍ͨͳ΍ͭ • enterͨ͠ͱ͖͸؆୯ʹͰ͖͚ͨͲɺleave࣌ ʹΞχϝʔγϣϯΛ଴ͨͣʹফ͑ͯ͠·͏

Slide 37

Slide 37 text

書いた

Slide 38

Slide 38 text

function changeClass (item, action, name) { item.classList[action]('riot-'+name) } function init () { this.elements = [] const requestAnimation = function () { for (let i = 0; i { changeClass(item, 'add', action == 'show' ? 'hide-leave-active' : 'hide-add-active') }, 0) let onAnimationEnd = function () { changeClass(item, 'remove', action == 'show' ? 'hide-leave-active' : 'hide-add-active') changeClass(item, 'remove', action == 'show' ? 'hide-leave' : 'hide-add') if (action == 'hide') changeClass(item, 'add', 'hide') item.removeEventListener('animationend', onAnimationEnd, false) item.removeEventListener('transitionend', onAnimationEnd, false) } item.addEventListener('animationend', onAnimationEnd, false) item.addEventListener('transitionend', onAnimationEnd, false) } }.bind(this) this.on('mount', function () { this.elements = this.root.querySelectorAll('[animate]') }) this.on('update', function () { for (var i = 0; i

Slide 39

Slide 39 text

animate target
example { &[animate] { transition: 500ms linear; &.riot-hide { display: none; } &.riot-hide-leave { opacity: 0; &.riot-hide-leave-active { opacity: 1; } } &.riot-hide-add { opacity: 1; &.riot-hide-active { opacity: 0; } } } } this.mixin(require('riot-animate-show'))

Slide 40

Slide 40 text

まとめ 40

Slide 41

Slide 41 text

まとめ • riot.routeຐվ଄ͨ͠ • ௒ௐ੔த • jQueryPluginศར • ؆୯ʹ࢖͑Δ • animateࣗ࡞ͨ͠ • ΍ͬͺΓRiot͸͕͜͜ऑ͍ 41

Slide 42

Slide 42 text

さいごに ϞόΠϧϑΝΫτϦʔͰ͸ɺ JavaScript͕େ޷͖ͳΤϯδχΞΛืू͓ͯ͠Γ·͢ʂ 42