Giới thiệu

Hôm nay mình sẽ tạo một ứng dụng (single-page) có sự kết hợp giữa VueJS và Firebase.
Single-page application (SPA) là gì ?
Với một trang web truyền thống, khi người dùng yêu cầu một trang web, thì server sẽ tính toán và trả về trang web đó cho người dùng toàn bộ trang web dưới dạng mã html. Hầu như không có bất kỳ sự liên kết nào giữa 2 yêu cầu gần nhau. Do đó khi có nhiều yêu cầu được diễn ra thì sẽ làm quá trình tính toán diễn ra lâu hơn, bởi hệ thống phải tính toán nhiều thành phần trước khi trả về một trang web hoàn chỉnh.

Với SPA lại khác, ở lần request đầu tiên, hệ thống sẽ trả về tất cả code xử lý cũng như code hiển thị của toàn bộ trang web, ở những yêu cầu tiếp theo client chỉ phải requets những phần nào mình cần, và server sẽ trả về dữ liệu dưới dạng thô, giúp rút ngắn thời gian truyền tải, giúp nâng cao trải nghiệm của người dùng hơn.
Firebase là gì ?
Theo Wikipedia, thì “Firebase is a mobile and web application platform with tools and infrastructure designed to help developers build high-quality apps“.
Firebase là một nền tảng di động giúp bạn nhanh chóng phát triển các ứng dụng chất lượng cao, phát triển ứng dụng cho người dùng lớn, và kiếm được nhiều tiền hơn.
FireBase có thể rất mạnh mẽ đối với ứng dụng backend, nó bao gồm việc lưu trữ dữ liệu, xác thực người dùng, static hosting……Nên lập trình viên chỉ cần chú tâm đến việc nâng cao trải nghiệm người dùng.

Nội dung

Link github: https://github.com/vanquynguyen/fbook-vuejs

Link demo: https://vanquynguyen.github.io/fbook-vuejs/

Tạo một tài khoản firebase
Truy cập: https://firebase.google.com/ sau đó đăng nhập tài khoản google. Sau khi đã đăng nhập thành công. Click vào Get Started

Hoặc bạn có thể truy cập trực tiếp vào link này: https://console.firebase.google.com/
Tạo 1 project cho mình:

Sau khi tạo xong project click vào project:

Và đây là giao diện dashboard quản lý của firebase:

Trên sidebar menu chọn Database->Rules sau đó sửa như hình:

Vậy là bạn đã khởi tạo firebase xong giờ cùng đi vào code nhé!
Tạo project VueCLI

Nếu không tạo được project có thể tham khảo cách tạo VueCLI ở đây : https://viblo.asia/p/tao-ung-dung-effect-dep-mat-voi-transitions-animation-vuejs-Az45bbdo5xY

 $ vue init webpack vue-cli-timetable

Bắt đầu vào code nhé =))
Chắc rằng bạn hiểu cách quản lý và chạy của VueCLI nhé, có thể tham khảo: https://viblo.asia/p/ban-biet-gi-ve-webpack-WAyK81wWZxX
Cài đặt npmfirebase

 $ npm install
 $ npm install firebase vuefire --save

👌👌👌Oke Oke
Cấu trúc project:

 fbook-vuejs
  
+ |- dist
+   |- build.js
+ |- /src
+   |- assets
+   |- App.vue
+   |- main.js
+ |- index.html
+ |- package-lock.json
+ |- package.json
+ |- webpack.config.js

Trong file main.js, import các package cần thiết

import Vue from 'vue'
import App from './App.vue'
import VueFire from 'vuefire'

Vue.use(VueFire)

new Vue({
 el: '#app',
 render: h => h(App)
})

Trong Index.html, gọi link CDN cho nhanh nhé =)))

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Fbook-VueJS</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css" />
    <!-- jQuery library -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <!-- Latest compiled JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <script src="/dist/build.js"></script>
  </body>
</html>

Kết nối với firebase
Trong Project Overview click vào Add Firebase to your web app:

import Firebase from 'firebase'
let config = {
        apiKey: "...", 
        authDomain: "...", 
        databaseURL: "...",
        storageBucket: "...",
        messagingSenderId: "..."
    };
      
    let app = Firebase.initializeApp(config)
    let db = app.database()
    let booksRef = db.ref('books')

Khi thao tác dữ liệu chúng ta sẽ phải tham chiếu lên firebase bằng app.database(). Cuối cùng có thể lấy được tham chiếu trong dữ liệu books trên firebase với let booksRef = db.ref(‘books’). Sử dụng VueFire giúp việc lấy dữ liệu trở nên dễ dàng hơn, đơn giản chỉ cần gọi.

firebase: {
    books: booksRef
},

Giờ chúng ta đã có dữ liệu books lấy từ firebase và nó sẽ được render trong đoạn code này.

<div class="panel-body">
    <table class="table table-striped">
        <thead>
            <tr>
                <th>Title</th>
                <th>Author</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="book in books" v-bind:key="book['.key']">
                <td><a v-bind:href="book.url">{{book.title}}</a></td>
                <td>{{book.author}}</td>
                <td><span class="glyphicon glyphicon-trash" aria-hidden="true" v-on:click="removeBook(book)"></span></td>
            </tr>
        </tbody>
    </table>
</div>

Khởi tạo thuộc tính newBook và thuộc tính này là rỗng nhé.

data () {
    return {
        newBook: {
            title: '',
            author: '',
            url: 'http://'
        },
    }
},

Code cho chức năng Add Book:

<div class="panel-body">
    <form id="form" class="form-inline" v-on:submit.prevent="addBook">
        <div class="form-group">
            <label for="bookTitle">Title:</label>
            <input type="text" id="bookTitle" class="form-control" v-model="newBook.title">
        </div>
        <div class="form-group">
            <label for="bookAuthor">Author:</label>
            <input type="text" id="bookAuthor" class="form-control" v-model="newBook.author">
        </div>
        <div class="form-group">
            <label for="bookUrl">Url:</label>
            <input type="text" id="bookUrl" class="form-control" v-model="newBook.url">
        </div>
        <input type="submit" class="btn btn-primary" value="Add Book">
    </form>
</div>
methods: {
   addBook() {
       booksRef.push(this.newBook);
       this.newBook.title = '';
       this.newBook.author = '';
       this.newBook.url = 'http://';
       toastr.success('Book added successfully')
   }
},

Code cho chức năng Remove Book:

<td><span class="glyphicon glyphicon-trash" aria-hidden="true" v-on:click="removeBook(book)"></span></td>
removeBook(book) {
    booksRef.child(book['.key']).remove()
    toastr.success('Book removed successfully')
}

Và cả file App.vue:

<template>
  <div id="app" class="container">
      <div class="page-header">
          <h1><img src="http://book.framgia.vn/images/icon.jpg" alt="" width="67" height="60"><span>FBook</span></h1>
      </div>
      <div class="panel panel-default">
          <div class="panel-heading">
              <h3 class="panel-title">Add New Books</h3>
          </div>
          <div class="panel-body">
              <form id="form" class="form-inline" v-on:submit.prevent="addBook">
                  <div class="form-group">
                      <label for="bookTitle">Title:</label>
                      <input type="text" id="bookTitle" class="form-control" v-model="newBook.title">
                  </div>
                  <div class="form-group">
                      <label for="bookAuthor">Author:</label>
                      <input type="text" id="bookAuthor" class="form-control" v-model="newBook.author">
                  </div>
                  <div class="form-group">
                      <label for="bookUrl">Url:</label>
                      <input type="text" id="bookUrl" class="form-control" v-model="newBook.url">
                  </div>
                  <input type="submit" class="btn btn-primary" value="Add Book">
              </form>
          </div>
      </div>
      <div class="panel panel-default">
          <div class="panel-heading">
              <h3 class="panel-title">Book List</h3>
          </div>
          <div class="panel-body">
              <table class="table table-striped">
                  <thead>
                      <tr>
                          <th>Title</th>
                          <th>Author</th>
                          <th></th>
                      </tr>
                  </thead>
                  <tbody>
                      <tr v-for="book in books" v-bind:key="book['.key']">
                          <td><a v-bind:href="book.url">{{book.title}}</a></td>
                          <td>{{book.author}}</td>
                          <td><span class="glyphicon glyphicon-trash" aria-hidden="true" v-on:click="removeBook(book)"></span></td>
                      </tr>
                  </tbody>
              </table>
          </div>
      </div>
  </div>
</template>
<script>
  import Firebase from 'firebase'
  import toastr from 'toastr'

  let config = {
      apiKey: "...",
      authDomain: "...",
      databaseURL: "...",
      storageBucket: "...",
      messagingSenderId: "..."
  };

  let app = Firebase.initializeApp(config)
  let db = app.database()
  let booksRef = db.ref('books')

  export default {
      name: 'app',
      data () {
          return {
              newBook: {
                  title: '',
                  author: '',
                  url: 'http://'
              },
          }
      },
      firebase: {
          books: booksRef
      },
      methods: {
          addBook() {
              booksRef.push(this.newBook);
              this.newBook.title = '';
              this.newBook.author = '';
              this.newBook.url = 'http://';
              toastr.success('Book added successfully')
          },
          removeBook(book) {
              booksRef.child(book['.key']).remove()
              toastr.success('Book removed successfully')
          }
      },
  }
</script>
<style>
  #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      color: #2c3e50;
      margin-top: 20px;
  }
</style>

Chạy thử và cảm nhận nhé

Lời kết

Qua bài viết chúng ta đã có những hiểu biết nhất định về single-page application(SPA) và áp dụng hiệu quả vuejs và firebase. Hy vọng các bạn có thể viết được single-page cho riêng mình. Theo dõi Theo dõi series 2018 – Cùng nhau học VueJS còn nhiều điều lý thú ở phần sau đấy 😜😜😜