4
\$\begingroup\$

I am "discovering" Firebase and I'm trying create simple chat with Vue, Vuex and Firebase. But because I'm just starting out with Vue, I need code review or advices from more experienced programmers. I need to know whether this code is properly structured - if it is well written in "Vue way" - and how to make my components better - more universal / better separated from rest of the code.

jsFiddle

var uid = null

var firebaseConfig = {
  apiKey: "AIzaSyDGYiab8xoIXIgbFSmLSwXubNL2T3Rr6AQ",
  authDomain: "first-steps-6abb2.firebaseapp.com",
  databaseURL: "https://first-steps-6abb2.firebaseio.com"
}

var store = new Vuex.Store({
  state: {
    messages: []
  },
  mutations: {
    addMessage (state, message) {
      state.messages.push(message)
      if (state.messages.length > 10) {
        state.messages.shift()
      }
    }
  }
})

var listMessages = {
  template: `
    <ul class="list-messages">
      <li v-for="message in messages">
        <span>{{message.time}}</span> {{ message.text }}
      </li>
    </ul>
  `,
  data () {
    return {
      messages: this.$store.state.messages
    }
  }
}

var addMessage = {
  template: `
    <div class="add-message">
      <label for="message">Add new:</label>
      <input id="message" @keyup.enter v-model="message">
      <button @click="sendMsg">Send</button>
    </div>
  `,
  data () {
    return {
      message: ''
    }
  },
  methods: {
    sendMsg () {
      messages.push().set({
        uid: uid,
        content: this.message,
        timestamp: firebase.database.ServerValue.TIMESTAMP
      })
      this.message = ''
    }
  }
}

firebase.initializeApp(firebaseConfig)
firebase.auth().signInAnonymously()
firebase.auth().onAuthStateChanged(function (user) {
  if (user) { uid = user.uid }
})

new Vue({
  el: '#app',
  store,
  components: {
    listMessages,
    addMessage
  }
})

var db = firebase.database()
var messages = db.ref('messages')
var query = messages.orderByChild('timestamp').limitToLast(10)

query.on('child_added', function (data) {
  store.commit('addMessage', {
    uid: data.val().uid,
    text: data.val().content,
    time: moment(data.val().timestamp).format('hh:mm:ss')
  })
})
html, body {
  margin: 0;
  height: 100%;
}
.container {
  min-height: 100%;
  position: relative;
}
.list-messages {
  position: absolute;
  box-sizing: border-box;
  width: 100%;
  top: 10px;
  margin: 0;
  padding: 10px;
  list-style: none;
}
.list-messages span {
  color: lightblue;
}
.add-message {
  text-align: center;
  position: absolute;
  width: 100%;
  bottom: 10px;
}
<div id="app" class="container">
  <list-messages></list-messages>
  <add-message></add-message>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-database.js"></script>

\$\endgroup\$
2
\$\begingroup\$

The code looks pretty straight-forward and I don't spot any obvious simplifications. I would suggest that you add error handling - especially for the case when uid is not null and remains that way. Perhaps an error message should be added if the request for the appropriate value fails.


Since is used (e.g. with the template literals) const could be used instead of var for any variable that doesn't get re-assigned (e.g. the components, db, etc.) and let for other variables (e.g. uid).


You could also consider providing a key attribute on the v-for where the messages are displayed, but the markup is quite simple for those so it may not add any benefit.

It is recommended to provide a key with v-for whenever possible, unless the iterated DOM content is simple, or you are intentionally relying on the default behavior for performance gains.1

1https://vuejs.org/v2/guide/list.html#key

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy