β

[译]Vue.js 结合 Firestore 实际应用

JDC | 京东设计中心 118 阅读

Vue.js 结合 Firestore 实际应用

作者: Lukas van Driel | 译:永无止晋
原文地址: https://www.smashingmagazine.com/2018/04/vuejs-firebase-firestore/

你想做一个网站或者APP,竟然没有服务器?竟然没有数据库?竟然没有域名?你还不会后端技术?那都不是事儿!本文讲解如何利用 Firestore 配合 vue.js 做一个“八卦”网站。
ps: 访问 firebase 控制台需要“蓝灯”等网络代理

Firestore 是 Google Firebase 的一种新的数据存储方式(目前处于测试阶段),它以 Firebase 实时数据库为基础,且增加了一些漂亮的功能。在本文中,我们将使用 Vue.js 和 Firestore 建立一个网站。

假设你想制作一个新的产品(例如下一个 Twitter ,Facebook 或 Instagram )。 首先,你要制作本产品的原型或最小可行产品,即 MVP (Minimum Viable Product), 这样尽可能快地构建应用程序的核心,以便你可以将其展示给用户获取反馈并分析使用情况。这样用最短的时间完成,后续也可以快速迭代。

开始之前,我们先来给这个产品起一个厉害的名字,我们就叫它 “Amazeballs” 。

下面是我预想的设计:

Amazeballs 的定位是—–一个与朋友们分享生活中的“八卦”的应用。网站分为两部分,上面区域,我们放一个输入表单用来发表你的“八卦”,下面用来展示好友们的“八卦”。

构建一个 MVP ,你需要能够快速实现功能,随后可以灵活的添加和更改功能的工具。Amazeballs 的技术选型为 Vue.js( JavaScript 渲染框架),并用 Firebase(by Google)以及他的实时数据库—- Firestore 提供支持。

Firestore 可以使用传统的HTTP请求直接访问,可以让你在没有任何服务器的情况下在线存储数据,这使得它成为一个完整的后端即服务解决方案。

以上听起来可能有点挑战性,但其实很容易,我会引导你一步一步的创建和托管这个网站。不要看这篇文章有一个长长的滚动条,它并没有很多步骤。当然,如果你想直接看这个项目的源码,你可以在 GitHub 上下载并运行程序

让我们开始吧

我们从 Vue.js 开始,这是一个非常适合 JavaScript 初学者的框架,别小看了它,它包含了很多强大的功能,可以从 HTML 开始并逐渐添加逻辑,这也使它成为我前端框架的首选。

Vue.js有一个 搭建项目脚手架的命令行界面(CLI) 。 我们将使用它快速搭建项目开发环境。 首先,安装 CLI ,然后使用它来创建基于 webpack-simple 模板的新项目。

npm install -g vue-cli
vue init webpack-simple amazeballs

如果您按照以上截图上的步骤( npm install和npm run dev ),浏览器将打开一个大 Vue.js 徽标。

恭喜你,项目的脚手架已经搭建成功,好的开头是成功一半哦。

下一步,我们需要创建一个 Firebase 项目,打开 firebase 控制台 (由于网络问题,控制台打开过程可能有点慢,请耐心等待),点击添加项目创建一个项目。一个项目从免费的 Spark 计划开始,它为您提供有限的数据库(1 GB 数据,每天读取5万次)和1 GB 托管。 这对我们的 MVP 来说已经绰绰有余。当访问量不断增大时,可以升级配置。

点击“将 Firebase 添加到您的网页应用”来查看你需要的配置信息。我们将在应用程序中使用这个配置,和 Vue.js 的状态管理 配合使用使一种很好的方式。

首先运行 npm install firebase 安装 firebase ,然后创建一个文件 src/store.js 。这个文件将会被用来做状态管理,让每一个 Vue 组件都可以独立于组件树去访问它。以下是该文件的内容:

import Vue from 'vue';
import firebase from 'firebase/app';
import 'firebase/firestore';
import 'firebase/auth';

// 初始化 Firebase, 从云控制台辅助
var config = {
    apiKey: "AIzaSyCsXiKteCMbIhsDpGK277SR8A8P3HOjC8U",
    authDomain: "amazealls-24823.firebaseapp.com",
    databaseURL: "https://amazealls-24823.firebaseio.com",
    projectId: "amazealls-24823",
    storageBucket: "amazealls-24823.appspot.com",
    messagingSenderId: "187582214062"
};
firebase.initializeApp(config);

// 共享状态对象,即任何vue组件
// 可以访问
export const store = {
    ballsInFeed: null,
    currentUser: null,
    writeBall: (message) => console.log(message)
};

现在我们将添加 Firebase 部分的功能。用下面代码获取 Firestore 数据:

// 引用balls
const ballsCollection = firebase.firestore().collection('balls');
// onSnapshot 在数据改变时执行
// 在底层的firestore集合中进行更改
// 它将通过一个引用数组传递给
// 与你的查询匹配的文档
ballsCollection
    .orderBy('createdOn', 'desc')
    .limit(5)
    .onSnapshot((ballsRef) => {
        const balls = [];
        ballsRef.forEach((doc) => {
        const ball = doc.data();
        ball.id = doc.id;
        balls.push(ball);
    });
console.log('Received Balls feed:', balls);
store.ballsInFeed = balls;
});

然后用 firebase 的一个写入方法替换 writeBall 函数。

writeBall: (message) => ballsCollection.add({
    createdOn: new Date(),
    author: store.currentUser,
    message
})

注意两者如何完全解耦。 当你插入一个集合时,执行了 add 方法, onSnapshot 也会被触发。 这使得我们的状态管理变得更容易。

现在有了一个共享的状态对象,任何Vue组件都可以很容易访问。接下来,让我们好好利用它。

接下来的工作

首先,让我们看看当前的用户是谁。

Firebase 有身份验证 api ,可以替你分担一些关于用户的工作。打开 Firebase 控制台 ,进入你刚刚创建的项目,然后依次点击 Authentication 登录方法 ,来启动适当的身份验证选项。现在,我们用一个非常普通的按钮来使用 Google 登录。

Firebase 不会提供任何界面帮助,因此您必须创建自己的“使用 Google / Facebook / Twitter 登录”按钮和用户名/密码输入字段。 您的登录组件可能看起来有点像这样:

<template>
    <div>
        <button @click.prevent="signInWithGoogle">Log in with Google</button>
    </div>
</template>

<script>
import firebase from 'firebase/app';
import 'firebase/auth';

export default {
    methods: {
        signInWithGoogle() {
            var provider = new firebase.auth.GoogleAuthProvider();
            firebase.auth().signInWithPopup(provider);
        }
    }
}
</script>

现在,我们遇到一个小难题,如何把 currentUser 变量放到 store 里。把下面代码加进你的 store.js

// 当一个用户登录或登出时,保存这个动作到store
firebase.auth().onAuthStateChanged((user) => {
    store.currentUser = user;
});

有了这三行,每当当前登录的用户更改(登录或注销)时, store.currentUser 也会更改。登录搞定了, 让我们发布一些“八卦”吧。

输入表单是一个单独的 Vue.js 组件,它连接到我们 store 中的 writeBall 函数,如下所示:

<template>
    <form @submit.prevent="formPost">
        <textarea v-model="message" />
        <input type="submit" value="DUNK!" />
    </form>
</template>

<script>
import { store } from './store';

export default {
    data() {
        return {
            message: null,
        };
    },
    methods: {
        formPost() {
            store.writeBall(this.message);
        }
    },
}

很好,现在用户可以登录并发布“八卦”了。但是,我们还缺少授权功能,这就倒了 Firestore 的用武之地。它们由 Javascript 代码组成,定义了对数据库的访问权限。你可以通过 Firestore 控制台输入它们,也可以使用 Firebase CLI 安装它们。按照以下命令安装并运行(不要使用git 的命令行终端):

npm install -g firebase-tools
firebase login
firebase init firestore

完成上述步骤,在你的工程里你可以看到一个 firestore.rules 文件,你可以在这里添加你应用的授权。我们希望每个用户只能添加自己的“八卦”,而不是添加或编辑别人的“八卦”。下面有一个不错的例子,它允许每个人读取数据库中的所有文档,但只有在登录后才能添加,并且插入的数据有一个字段 “author” ,就是当前登录的用户名。

service cloud.firestore {
    match /databases/{database}/documents {
        match /{document=**} {
            allow read: if true;
            allow create: if request.auth.uid != null && request.auth.uid == request.resource.data.author;
        }
    }
}

别小看这几行代码,它很强大,可以快速的实现一些复杂功能。 Firebase 正在围绕此部分开发更好的工具,在能完全满足我们的需求前,它将一直处于反复的测试阶段。

现在你可以运行 firebase deploy ,Firestore 规则将在数秒内部署并保护你的生产数据。

添加服务逻辑

在你的主页上,你想看到你的朋友们的“八卦”的时间线,取决于你想让用户看到哪些八卦,直接在数据库上执行这个查询可能会成为性能障碍。有一种解决方案是,是创建一个 Firebase 云端服务,在每个发布的“八卦”上激活并给所有作者的朋友查看的权限。这样它就是异步的,非阻塞的,并且最终一致的。

以上说的过于抽象,下面我来演示一个小小的例子,监听“八卦”的创建并修改他们的消息。 下面让我们看一下如何让云功能正常运行。

运行以下命令:

firebase init functions

初始化完成后,工程中会创建一个 functions 文件夹,你可以在 index.js 中编写自己的云端功能的文件,如果您对它印象深刻,不要直接复制粘贴我的云功能函数。

const functions = require('firebase-functions');
exports.createBall = functions.firestore
    .document('balls/{ballId}')
    .onCreate(event => {
        var createdMessage = event.data.get('message');
        return event.data.ref.set({
        message: createdMessage + ', yo!'
    }, {merge: true});
});

云功能函数会把你的应用程序划分为不同的部分并让它们异步通信。 应用程序不同组件之间的异步通信如下图所示:

最后一步:部署

Firebase 有自己的托管选项来实现部署,用命令行工具执行以下命令:

firebase init hosting

选择 dist 文件夹作为一个公共目录,然后选择 “Yes” 把所以 URL 指向 index.html 。最后一个选项可以允许你使用 vue-router 来管理你应用的页面跳转。

进行到这一步,还有一个小障碍: dist 文件夹里面没有包含 index.html 文件,我们在 package.json 中添加以下 npm 脚本

{
    "scripts": {
        "deploy": "npm run build && mkdir dist/dist && mv dist/*.* dist/dist/ && cp index.html dist/ && firebase deploy"
    }
}

现在只需运行 npm deploy ,用成功运行后给出的URL在浏览器访问即可!

何时使用这个架构

Firebase 非常适合做 **MVP** 。等你用这个架构做过两到三个项目时,你可以在几分钟内拥有一个免费托管的,可扩展数据库支持的应用,并且可以快速开始实现一些功能。

此外,这套架构还有很大的发展空间,如果现有云功能满足不了你的需求,你还可以使用 Google Cloud 的一些常用的API来替代它。此外,你可以使用 vue-router 和 vuex 升级你的 Vue.js 体系结构,并可以配合 webpack 和 vue-cli 实现更强大的功能。

但它也不是十全十美的,最大的一个问题是,用户可以直接操作你的数据库,没有中间层可以用来将原始数据转换成更容易为客户端所用的格式。所以,你必须以更友好的的方式存储它。还有,每当客户更改需求的时候,你会发现在 Firebase 上进行数据迁移很困难。为此,你需要编写一个定制的 Firestore 客户端来读取每条记录,进行转换并写回。

是不是想问现在有哪些应用实例? Laravel GitLab nu.nl 这些“大牌”都在配合 vue.js 使用Firebase 。Firestore 仍处于测试阶段,因此目前还没有很多活跃的用户,但 Firebase 套件已被美国国家公共广播,Shazam 等用户使用。我身边也有同事为基于 Unity 的游戏 “ Road Warriors ” 实施了 Firebase ,并在前五天内下载了超过一百万次。它可能需要相当多的负载,并且对于 Web ,本地移动设备,Unity等客户端来说非常灵活。

如果你想学习更多,请参考以下代码

本文的例子 ,包含本文所有代码
Vue.js , vue-router , vue-cli 的文档
Firebase 的文档
-更好地了解 Firebase 的有趣方式— their YouTube Blog

更多内容请关注我们团队的公众账号“全栈探索”。定期会有好文推送,满满的干货。

作者:JDC | 京东设计中心
京东设计中心
原文地址:[译]Vue.js 结合 Firestore 实际应用, 感谢原作者分享。

发表评论