Praktické príklady s Vue – 3/x

Tento príklad je “vrcholom” z zmysle, že kým v prvom sme si predviedli vykreslenie vymyslených údajov AJAX-om, v druhom už to boli reálne údaje získavané v reálnom čase cez WebSockets, tak v tomto príklade si vykreslujeme údaje tiež v reálnom čase, ale tento krát vlastné, s pomocou Firebase.

Jednoduchý “serverless” chat

Tento krát je kód naprosto jednoduchý a z vlastností Vue prakticky takmer nové neukazuje. Ale tento krát ide o to, aby ste si uvedomili, že s platformami ako Firebase, alebo Kinvey ani len nepotrebujete server – tvoríte takzvané “serverless” aplikácie. Avšak pozor. Napriek tomu označeniu “serverless” je to však klasická aplikácia.  V konečnom dôsledku nič také ako “serverless” neexistuje. Tou “bezserverovosťou” je myslené skôr to, že si nemusíte prenajímať vlastný virtuálny server, rozbehávať na ňom minimálne Node, Webpack a nejakú databázu, ale že si prenajmete už hotový, nakonfigurovaný server poskytovaný ako službu. BaaS – Backend as a Service. A keďže aj to je dnes vo svete obľúbený prístup k tvorbe web aplikácií, tak nech o ňom viete a nech máte aspoň jednoduchú ukážku ako na to:

<style>
.container {
  border: 1px solid black;
  width: 500px;
  margin: 0 auto;
  padding: 0 5px;
  background-color: white;
  position: relative;
}
.new-msg {
  padding: 10px 0;
  text-align: center;
}
</style>

<div id="app" class="container">
    <div class="new-msg">
      <input @keydown.enter="sendMsg" v-model="message" maxlength="140">
      <button @click="sendMsg">&crarr;</button>
    </div>
    <ul>
      <li v-for="(msg, idx) in descending" :key="idx">
        <div class="header">
          <span class="user">
            <span v-html="userIcon"></span> {{ msg.user }}
          </span>
          <span class="time">
            <span v-html="timeIcon"></span> {{ msg.time }}
          </span>
        </div>
        <p>{{ msg.text }}</p>
      </li>
      </ul>
</div>

<script src="https://unpkg.com/moment@2.18.1/min/moment.min.js"></script>
<script src="https://unpkg.com/vue@2.4.4/dist/vue.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.4.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.4.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.4.0/firebase-database.js"></script>

<script>
  new Vue({
    el: '#app',
    data: {
      user: '',
      message: '',
      messages: [],
      fb: null,
      db: null,
      table: null,
      query: null,
      fbConf: {
        apiKey: 'AIzaSyAmSOSEmbX_UqIXjZqUMqlIAdfK7SC8VBI',
        authDomain: 'hat-a132d.firebaseapp.com',
        databaseURL: 'https://chat-a132d.firebaseio.com'
      },
      userIcon: `
        <svg id="i-user" viewBox="0 0 32 32" width="16" height="16" fill="none" stroke="currentcolor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
          <path d="M22 11 C22 16 19 20 16 20 13 20 10 16 10 11 10 6 12 3 16 3 20 3 22 6 22 11 Z M4 30 L28 30 C28 21 22 20 16 20 10 20 4 21 4 30 Z" />
        </svg>
      `,
      timeIcon: `
        <svg id="i-clock" viewBox="0 0 32 32" width="14" height="14" fill="none" stroke="currentcolor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
          <circle cx="16" cy="16" r="14" />
          <path d="M16 8 L16 16 20 20" />
        </svg>
      `
    },
    computed: {
      descending () {
        return Array.from(this.messages).reverse()
      }
    },
    methods: {
      logIn (user) {
        this.user = user.uid.substr(0, 8)
      },
      sendMsg () {
        if (this.message) {
          this.table.push().set({
            user: this.user,
            timestamp: this.fb.database.ServerValue.TIMESTAMP,
            content: this.message
          })
          this.message = ''
        }
      },
      listMsg (data) {
        if (this.messages.length > 19) {
          this.messages.shift()
        }
        this.messages.push({
          user: data.val().user,
          time: moment(data.val().timestamp).format('HH:mm:ss'),
          text: data.val().content
        })
      }
    },
    created () {
      this.fb = firebase
      this.fb.initializeApp(this.fbConf)
      this.fb.auth().signInAnonymously()
      this.fb.auth().onAuthStateChanged(this.logIn)
      this.db = this.fb.database()
      this.table = this.db.ref('messages')
      this.query = this.table.orderByChild('timestamp').limitToLast(20)
      this.query.on('child_added', this.listMsg)
    }
  })
</script>

[iframe src=”https://jsfiddle.net/provuecateur/27fpjgv0/embedded/result,html,css,js/” width=”100%” height=”910″]