Slide 1

Slide 1 text

ੲջ͔͍͠Πϯλʔωοτͷ෩෺ࢻΛ ࠷ۙͷٕज़Ͱ࡞Δ࿩ 2018/09/01(౔) ߹ಉษڧձ in େ౎ձԬࢁ -2018 Summer- ҳݟ੣ (@mako_wis)

Slide 2

Slide 2 text

About Me ҳݟɹ੣ʢϔϯϛɹϚίτʣ T witter: @mako_wis GitHub: makowis גࣜձࣾΫϨΦϑʔΨ Engineering Manager Okayama.rb ΠϕϯτཱͯΔ܎ɺதࠃ஍ํDBษڧձ Ԭࢁελοϑ झຯɿΨϯϓϥ੡࡞ɺϓϩάϥϛϯά

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

ԻָܥͷձࣾͳͷͰ

Slide 5

Slide 5 text

Իָ࡞ΕΔਓ͕ଟ͍

Slide 6

Slide 6 text

M3ʹࣾ಺ͷϝϯόʔͰ ԻָCDΛग़͢Β͍͠

Slide 7

Slide 7 text

๻͸Իָ࡞Εͳ͍ͷͰ

Slide 8

Slide 8 text

ϗʔϜϖʔδ࡞ͬͯΈͨ

Slide 9

Slide 9 text

ϓϩτλΠϓ ๭ΞχϝͬΆ͍ϩΰ จࣈΛ఺໓ͤͨ͞ΓεΫ ϩʔϧͤͨ͞Γ͍ͯ͠ ੲջ͔͍͠ײ͡ʹ͔ͨͬ͠ ͨ

Slide 10

Slide 10 text

࢖ΘΕͯΔݹͷ෩෺ࢻ blinkͱmarquee ϗʔϜϖʔδͷ૷০ͱ͍͑ ͹͜Ε λάͱͯ͠͸ഇࢭ CSSΞχϝʔγϣϯͰ࣮૷ ಈ࡞ݟ͍ͨਓ͸ʮblink htmlʯ΍ʮmarquee htmlʯ ͰάάΖ͏

Slide 11

Slide 11 text

blinkΛcss animationͰ࣮૷ @keyframes blink { 75% { opacity: 0; } } .blink { animation: blink 1s step-end infinite; }

Slide 12

Slide 12 text

͜Ε͕ҙ֎ͱࣾ಺Ͱ ΢έͯ͠·ͬͨ

Slide 13

Slide 13 text

ϓϩτλΠϓ৭ʑ໰୊ ͋Γͦ͏ͳͷͰ࡞Γ௚ͨ͠

Slide 14

Slide 14 text

ίϯηϓτ ʮੲջ͔͍͠ײ͡ʯ

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

https://teijigo-beer-ti.me/

Slide 17

Slide 17 text

։ൃϝϯόʔ

Slide 18

Slide 18 text

։ൃϝϯόʔ

Slide 19

Slide 19 text

։ൃϝϯόʔ ࣾ௕ ଞࣾͷਓ ଞࣾͷਓ

Slide 20

Slide 20 text

https://github.com/ makowis/teijigo-beer-time

Slide 21

Slide 21 text

ݹͷ෩෺ࢻ ΞΫηεΧ΢ϯλʔ Ұݴܝࣔ൘ ϑϨʔϜͬΆ͍σβΠϯ എܠʹը૾Λϕλ഑ஔ

Slide 22

Slide 22 text

ߏ੒ αΠτɿVue.js + T ypescript αʔόʔɿFirebase Hosting σʔλϕʔεɿFirebase Realtime Database

Slide 23

Slide 23 text

ջ͔͍͠ݟͨ໨Ͱ͕͢ ʮγϯάϧϖʔδΞϓϦέʔγϣϯʯ Ͱ͢

Slide 24

Slide 24 text

ΞΫηεΧ΢ϯλʔ τοϓϖʔδʹΞΫηεͰ Χ΢ϯτΞοϓ ϦϩʔυͰ΋Χ΢ϯτΞο ϓ ഉଞॲཧ͸ಛʹߟྀ͠ͳ ͍ ϑΝΠϧʹΧ΢ϯτ਺࣋ͬ ͯͨΞϨͳײ͡ͷ࣮૷

Slide 25

Slide 25 text

࣮૷ Χ΢ϯτͷอଘʹ͸Firebase Realtime DatabaseΛ࢖༻

Slide 26

Slide 26 text

Firebase Realtime Database NoSQLσʔλϕʔε σʔλ͸JSONܗࣜͰอଘ͞ΕΔ σʔλ͸઀ଓ͞Ε͍ͯΔΫϥΠΞϯτͱϦΞ ϧλΠϜʹಉظ͞ΕΔ

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

Firebase Realtime Databaseଆͷ४උ

Slide 29

Slide 29 text

Firebase΁ͷొ࿥͸ Ͱ͖͍ͯΔલఏͰ͍͖·͢

Slide 30

Slide 30 text

ίϯιʔϧͷDatabase͔Β Realtime DatabaseΛ࡞੒

Slide 31

Slide 31 text

ϩοΫϞʔυͰ։࢝ʢޙͰઃఆม͑·͢ʣ

Slide 32

Slide 32 text

access_counterͷϑΟʔϧυΛ௥Ճ͢Δ

Slide 33

Slide 33 text

ϧʔϧʹaccess_counter΁ͷΞΫηεݖΛઃఆ

Slide 34

Slide 34 text

઀ଓ৘ใͷ֬ೝ

Slide 35

Slide 35 text

ઃఆը໘ͷ ΢ΣϒΞϓϦʹFirebaseΛ௥ՃΛΫϦοΫ

Slide 36

Slide 36 text

઀ଓʹ࢖༻͢Δ৘ใΛ֬ೝͯ͠ϝϞ͓ͯ͘͠

Slide 37

Slide 37 text

Vue.jsଆͷ࣮૷

Slide 38

Slide 38 text

firebaseͷϥΠϒϥϦΛ௥Ճ // npmͷ৔߹ $ npm install firebase —save // yarnͷ৔߹ $ yarn add firebase

Slide 39

Slide 39 text

firebase-configΛ௥Ճ // src/firebase-config.js import firebase from 'firebase/app'; import 'firebase/database'; const config = { // ؅ཧը໘Ͱ֬ೝͨ͠databaseURLΛઃఆ͢Δ databaseURL: "https://teijigo-beer-time.firebaseio.com", }; firebase.initializeApp(config); // ࠓճ͸database͚ͩ࢖༻͢ΔͷͰdatabaseΛexport export default firebase.database();

Slide 40

Slide 40 text

ը໘ଆͷ࣮૷

TOP

͋ͳͨ͸{{ access }}ਓ໨ͷ๚໰ऀͰ͢ɻ

import firebase from 'firebase'; import database from '@/firebase-config'; export default { name: 'Top', data() { return { access: 0, }; }, created() { this.countUp(); }, methods: { countUp() { database .ref('access_counter') .once('value') .then((snapshot: firebase.database.DataSnapshot | null) => { if (snapshot) { // σʔλϕʔε͔Βऔಘͨ͠஋ʹ+1Λ͢Δ const access = parseInt(snapshot.val(), 10) + 1; // σʔλϕʔεͷ஋Λߋ৽͢Δ database.ref().update({ access_counter: access }); // ը໘දࣔ༻ͷม਺ʹ֨ೲ this.access = access; } }); }, }, };

Slide 41

Slide 41 text

Χ΢ϯτΞοϓͷॲཧ methods: { countUp() { database .ref('access_counter') .once('value') .then((snapshot: firebase.database.DataSnapshot | null) => { if (snapshot) { // σʔλϕʔε͔Βऔಘͨ͠஋ʹ+1Λ͢Δ const access = parseInt(snapshot.val(), 10) + 1; // σʔλϕʔεͷ஋Λߋ৽͢Δ database.ref().update({ access_counter: access }); // ը໘දࣔ༻ͷม਺ʹ֨ೲ this.access = access; } }); }, },

Slide 42

Slide 42 text

ը໘΁ͷදࣔ

TOP

͋ͳͨ͸{{ access }}ਓ໨ͷ๚໰ऀͰ͢ɻ

import firebase from 'firebase'; import database from '@/firebase-config'; export default { name: 'Top', data() { return { access: 0, }; }, created() { this.countUp(); },

Slide 43

Slide 43 text

ΞΫηεΧ΢ϯλʔ׬੒

Slide 44

Slide 44 text

؆୯Ͱ͢Ͷ

Slide 45

Slide 45 text

Ұݴܝࣔ൘ ΩϦ൪ใࠂ౳ʹ࢖͏ܝࣔ ൘ ϦΞϧλΠ Ϝߋ৽͕؆୯ͩͬ ͨͷͰ͍࣮ͭ૷ ੲͷܝࣔ൘ͱҧͬͯϦϩʔ υඞཁ͋Γ·ͤΜ

Slide 46

Slide 46 text

࣮૷ ίϝϯτͷอଘʹ͸Firebase Realtime DatabaseΛ࢖༻

Slide 47

Slide 47 text

Realtime Databaseଆͷ ઃఆ

Slide 48

Slide 48 text

ϧʔϧʹmessagesΛ௥Ճ͠·͢

Slide 49

Slide 49 text

Vue.jsଆͷ࣮૷

Slide 50

Slide 50 text

ը໘΁ͷදࣔ

Ұݴܝࣔ൘

HN(ϋϯυϧωʔϜ)
ϝοηʔδ
ૹ৴
  • {{item.message}} by {{item.name}}

    {{item.createdAt}}

import firebase from 'firebase'; import database from '@/firebase-config'; export default { name: 'Top', data() { return { name: '', message: '', messageList: [], }; }, created() { this.listen(); }, methods: { listen() { database .ref('messages/') .on('value', (snapshot: firebase.database.DataSnapshot | null) => { if (snapshot) { const list = snapshot.val(); const keys = Object.keys(list); const values = keys.map((v) => list[v]); this.messageList = values.sort((a: Message, b: Message) => { if (a.sortKey > b.sortKey) return 1; if (a.sortKey < b.sortKey) return -1; return 0; }); } }); }, sendMessage() { if (!this.name || !this.message) return; const message = { name: this.name, message: this.message, createdAt: moment(new Date()).format('YYYY/MM/DD H:mm:ss'), sortKey: -new Date(), }; database.ref('messages/').push(message); this.name = ''; this.message = ''; } }, };

Slide 51

Slide 51 text

ίϝϯτͷૹ৴
HN(ϋϯυϧωʔϜ)
ϝοηʔδ
ૹ৴
methods: { sendMessage() { if (!this.name || !this.message) return; const message = { name: this.name, message: this.message, createdAt: moment(new Date()).format('YYYY/MM/DD H:mm:ss'), sortKey: -new Date(), }; // σʔλϕʔεʹίϝϯτΛ௥Ճ database.ref('messages/').push(message); this.name = ''; this.message = ''; } }, };

Slide 52

Slide 52 text

ίϝϯτͷૹ৴ methods: { sendMessage() { if (!this.name || !this.message) return; const message = { name: this.name, message: this.message, createdAt: moment(new Date()).format('YYYY/MM/DD H:mm:ss'), sortKey: -new Date(), }; // σʔλϕʔεʹίϝϯτΛ௥Ճ database.ref('messages/').push(message); this.name = ''; this.message = ''; } }, };

Slide 53

Slide 53 text

ίϝϯτͷදࣔ listen() { database .ref('messages/') .on('value', (snapshot: firebase.database.DataSnapshot | null) => { if (snapshot) { const list = snapshot.val(); const keys = Object.keys(list); const values = keys.map((v) => list[v]); this.messageList = values.sort((a: Message, b: Message) => { if (a.sortKey > b.sortKey) return 1; if (a.sortKey < b.sortKey) return -1; return 0; }); } }); },

Slide 54

Slide 54 text

ίϝϯτͷදࣔ
  • {{item.message}} by {{item.name}}

    {{item.createdAt}}

import firebase from 'firebase'; import database from '@/firebase-config'; export default { name: 'Top', data() { return { name: '', message: '', messageList: [], }; }, created() { this.listen();

Slide 55

Slide 55 text

Ұݴܝࣔ൘׬੒

Slide 56

Slide 56 text

؆୯Ͱ͢Ͷ

Slide 57

Slide 57 text

·ͱΊ ੲͷջ͔͍͠΋ͷΛ࠷ۙͷٕज़Ͱ࠶࣮૷ͯ͠Έ· ͨ͠ ୯७ͳϞϊͳͷͰࢼ͠ʹ࡞ͬͯΈΔ୊ࡐͱͯ͠͸ ஸ౓͍͍ Firebase͜Ε͘Β͍ͷϞϊͰ͋Ε͹ແྉͰ࢖͑· ͢ Έͳ͞Μ΋࠶࣮૷ͯ͠Έ·͠ΐ͏

Slide 58

Slide 58 text

͓·͚

Slide 59

Slide 59 text

ϑϨʔϜͬΆ͍σβΠϯ ͬΆ͍σβΠϯͳͷͰϑ ϨʔϜ͸࢖͍ͬͯͳ͍ CSSͰͦΕͬΆ͘ݟͤͯ ·͢ ͍ͭ͜มܗ͠·͢

Slide 60

Slide 60 text

ϑϨʔϜͷมܗ ύιίϯ εϚʔτϑΥϯ

Slide 61

Slide 61 text

φ΢໊͍લΛ ߟ͑ͯ͘Εͨਓ͕͍·ͨ͠

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

#ϨεϙϯγϒϑϨʔϜ