一款使用Vue JS,Webpack&Material Design开发的渐进式web应用(PWA)[Part 2]

原文地址:https://medium.com/bam-tech/a-progressive-web-application-with-vue-js-webpack-material-design-part-2-a5f19e70e08b

pic1

这篇文章是A Progressive Web Application with Vue JS, Webpack & Material Design系列的其中一篇,旨在使用VueJS,Webpack和Material Design从头搭建一个基础但功能完整的PWA。如果你还没有看过之前的文章,可以点击这里阅读第一部分。

代码在GitHub开源:
https://github.com/charlesBochet/vueJSPwa

第一部分中,我们已经实现了使用VueJS,Webpack,MDL创建一个单页应用,并且实现了如下功能:
part 1 requirements

本系列教程的第二部分将会着眼于为Cropchat应用提供快速且实时更新的数据流。我们将做如下操作:

  • 配置一套新的Firebase数据库;
  • 使用Vuefire将Vue App连接至Firebase;
  • 向Firebase发送数据并取回。

firebase demo

[PART 2]使用Firebase实现一款数据实时更新的PWA


Firebase是谷歌出品的一款NoSQL实时数据库,它部署在云主机上所以你不需要安装任何东西。
数据在所有的客户端上都是实时同步的,这使得Firebase成为了创建聊天应用的理想工具:它提供了一个简单的方式去推送最新的消息,而且它是免费的。
若要了解更多信息,请参见官方页面
Let's start.

配置firebase

首先,前往Firebase Console,登录并创建一个新的项目:

firebase console

然后修改数据库规则:

database rules
注意:这个操作会允许任何人读取并操作你的数据库,它只适合使用在原型设计阶段。
将Firebase package添加至Cropchat:

npm install firebase --save

接下来我们需要建立和Firebase的连接。创建文件src/service/firebase.js,代码如下:

import firebase from 'firebase'

var config = {
 apiKey: <Your api key here>,
 authDomain: <Your auth Domain here>,
 databaseURL: <Your databaseUrl here>,
 storageBucket: <Your storageBucket here>,
 messagingSenderId: <Your messagingSenderId here>
}
firebase.initializeApp(config)

export default {
 database: firebase.database()
}

回到Firebase Console页面,选择Authentification标签。点击'WEB SETUP'按钮获取数据库的信息:
database info
至此我们已经成功连接到了数据库上。

Vuefire:释放Firebase+VueJS的能力

配置VueFire

我们将在项目中使用VueFire巴拉巴拉。添加VueFire到项目中:

npm install vuefire --save

src/main.js中引入VueFire:

import Vuefire from 'vuefire'

Vue.use(Vuefire)

src/main.js中引入firebase服务:

import firebase from './services/firebase'

new Vue({
 el: '#app',
 firebase: {
   cat: firebase.database.ref('cat').orderByChild('created_at')
 },
 router,
 template: '<App/>',
 components: { App }
})

以上操作将app的属性cats和firebase中的节点cats关联起来,VueFire会帮助我们实时同步数据。添加语句.orderByChild('created_at')使得返回的数据按照发布猫咪图片的时间倒序排列。

发布一条猫咪图片信息

我们可以开始尝试着向firebase数据库发送数据了。在src/components/PostView.vue中添加表格:

<template>
  <form>
    <div class="mdl-grid">
      <div class="mdl-cell mdl-cell--8-col">
        <div class="card-image__picture">
          <img :src="this.catUrl"/>
        </div>
      </div>
      <div class="mdl-cell mdl-cell--4-col mdl-cell--8-col-tablet">
        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label is-upgraded is-dirty">
          <input id="username" v-model="title" type="text" class="mdl-textfield__input"/>
          <label for="username" class="mdl-textfield__label">Describe me</label>
        </div>
        <div class="actions">
          <a @click.prevent="postCat" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
            POST A CAT
          </a>
        </div>
      </div>
    </div>
  </form>
</template>

添加Vue-resource和xml parser:

npm install vue-resource --save
npm install xml-parser --save

并在src/main.js中引入使用。

PostView.vuemounted()钩子中随机加载一张来自CatApi的猫咪图片:

<script>
  import parse from 'xml-parser'
  export default {
    data () {
      return {
        'catUrl': null
      }
    },
    mounted () {
      this.$http.get('https://thecatapi.com/api/images/get?format=xml&results_per_page=1').then(response => {
        this.catUrl = parse(response.body).root.children['0'].children['0'].children['0'].children['0'].content
      })
    },
    methods: {
    }
  }
</script>

最后在PostView.vuemethods中添加PostCat()方法,该方法会发送猫咪图片到Firebase数据库:

postCat () {
  this.$root.$firebaseRefs.cat.push(
    {
      'url': this.catUrl,
      'comment': this.title,
      'info': 'Posted by Charles on Tuesday',
      'created_at': -1 * new Date().getTime()
    })
    .then(this.$router.push('/'))
}

来吧,看一下现在的应用,点击'Plus'按钮前往发布猫咪图片页面:
PostView page

点击'Post A Cat'按钮,你应该可以看到在Firebase的概览中看到一条新条目:
new entry

渲染猫咪列表

胜利近在眼前!现在我们需要在HomeView中渲染从Firebase里取到的数据。在HomeView.vue<template>标签中插入以下代码:

<div v-for="picture in this.$root.cat" class="image-card" @click="displayDetails(picture['.key'])">
  <div class="image-card__picture">
    <img :src="picture.url" />
  </div>
  <div class="image-card__comment mdl-card__actions">
    <span>{{ picture.comment }}</span>
  </div>
</div>

别忘了删了已经不用了的模拟数据文件data.js和在HomeView.vue中对它的引用。
完成了之后就可以看一哈它长啥样了:

HomeView

更厉害的是,它的数据是实时同步的:

hot-synced

完善DetailView页面

老套路,添加一个loadash到项目里:

npm install lodash --save

然后把下面的代码写到DetailView.vue中:


<template>
  <div class="mdl-grid">
    <div class="mdl-cell mdl-cell--8-col">
      <div class="picture">
        <img :src="cat.url" />
      </div>
      <div class="info">
        <span>{{ cat.info }}</span>
      </div>
    </div>
    <div class="mdl-cell mdl-cell--4-col mdl-cell--8-col-tablet">
      <div class="comment">
        <span>{{ cat.comment }}</span>
      </div>
      <div class="actions">
        <router-link class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored" to="/post">
          ANSWER
        </router-link>
      </div>
    </div>
  </div>
</template>
<script>
  import { find } from 'lodash'
  export default {
    data () {
      return {
        cat: null
      }
    },
    mounted () {
      this.cat = find(this.$root.cat, (cat) => cat['.key'] === this.$route.params.id)
    }
  }
</script>

结论

长话短说,有这么几点微小的结论:

  • Vuefire提供快速而简单的方法将Firebase数据库集成到VueJS项目中;
  • Firebase是一款在应用中创建实时数据的强大的工具,可以让用户始终获取到最新的数据。

于是现在我们的未完成清单变成下面这样啦:
checklist

少侠别走!还有Part III等着你!