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

昔懐かしいインターネットの風物詩を最近の技術で作る話

Makoto Henmi
September 01, 2018

 昔懐かしいインターネットの風物詩を最近の技術で作る話

アクセスカウンター、一言掲示板など昔のインターネットにあったものがどんどん失われて行っています。
そんな過去の遺物たちをVue.jsとFirebaseを使って作った話をしました。

サイト: https://teijigo-beer-ti.me/
ソースコード: https://github.com/makowis/teijigo-beer-time

Makoto Henmi

September 01, 2018
Tweet

More Decks by Makoto Henmi

Other Decks in Programming

Transcript

  1. About Me ҳݟɹ੣ʢϔϯϛɹϚίτʣ T witter: @mako_wis GitHub: makowis גࣜձࣾΫϨΦϑʔΨ Engineering

    Manager Okayama.rb ΠϕϯτཱͯΔ܎ɺதࠃ஍ํDBษڧձ Ԭࢁελοϑ झຯɿΨϯϓϥ੡࡞ɺϓϩάϥϛϯά
  2. blinkΛcss animationͰ࣮૷ @keyframes blink { 75% { opacity: 0; }

    } .blink { animation: blink 1s step-end infinite; }
  3. 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();
  4. ը໘ଆͷ࣮૷ <template> <div> <h1>TOP</h1> <p>͋ͳͨ͸{{ access }}ਓ໨ͷ๚໰ऀͰ͢ɻ</p> </div> </template> <script>

    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; } }); }, }, }; </script>
  5. Χ΢ϯτΞοϓͷॲཧ 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; } }); }, },
  6. ը໘΁ͷදࣔ <template> <div> <h1>TOP</h1> <p>͋ͳͨ͸{{ access }}ਓ໨ͷ๚໰ऀͰ͢ɻ</p> </div> </template> <script>

    import firebase from 'firebase'; import database from '@/firebase-config'; export default { name: 'Top', data() { return { access: 0, }; }, created() { this.countUp(); },
  7. ը໘΁ͷදࣔ <template> <div> <h1>Ұݴܝࣔ൘</h1> <div class="message-form"> <div class="message-form-group"> <label for="nameInput">HN(ϋϯυϧωʔϜ)</label>

    <input type="text" id="nameInput" maxlength="20" v-model="name"> </div> <div class="message-form-group"> <label for="messageInput">ϝοηʔδ</label> <input type="text" id="messageInput" maxlength="100" v-model="message"> </div> <button type="button" @click="sendMessage">ૹ৴</button> </div> <div> <ul class="message-list"> <li v-for="(item, key) in messageList" v-bind:key="key"> <p> {{item.message}} by {{item.name}} </p> <p class="time-label"> {{item.createdAt}} </p> </li> </ul> </div> </div> </template> <script> 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 = ''; } }, }; </script>
  8. ίϝϯτͷૹ৴ <template> <div class="message-form"> <div class="message-form-group"> <label for="nameInput">HN(ϋϯυϧωʔϜ)</label> <input type="text"

    id="nameInput" maxlength="20" v-model="name"> </div> <div class="message-form-group"> <label for="messageInput">ϝοηʔδ</label> <input type="text" id="messageInput" maxlength="100" v-model="message"> </div> <button type="button" @click="sendMessage">ૹ৴</button> </div> </template> <script> 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 = ''; } }, }; </script>
  9. ίϝϯτͷૹ৴ <script> 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 = ''; } }, }; </script>
  10. ίϝϯτͷදࣔ 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; }); } }); },
  11. ίϝϯτͷදࣔ <template> <div> <ul class="message-list"> <li v-for="(item, key) in messageList"

    v-bind:key="key"> <p> {{item.message}} by {{item.name}} </p> <p class="time-label"> {{item.createdAt}} </p> </li> </ul> </div> </template> <script> import firebase from 'firebase'; import database from '@/firebase-config'; export default { name: 'Top', data() { return { name: '', message: '', messageList: [], }; }, created() { this.listen();