如何使用 vue 和 vuefire 加载 Firebase 数据?
Posted
技术标签:
【中文标题】如何使用 vue 和 vuefire 加载 Firebase 数据?【英文标题】:How do I load firebase data using vue and vuefire? 【发布时间】:2018-10-25 10:22:23 【问题描述】:我不明白如何将 firebase 数据导入 vue...一旦我得到答案,我很高兴删除这个问题或辞去我作为程序员的工作;)
我知道数据是异步的,所以 vue 试图在接收到数据之前渲染组件。但是,我不知道如何让它等待。示例将不胜感激。我试过阅读文档,但我就是不明白。
这是一个很小的应用程序,它显示我们公司的停车场并将用户的水龙头(汽车)位置保存到火力基地(我们厌倦了忘记我们停在哪里)。感谢您的帮助!
哦,我使用 set() 是因为一次只需要保存一个汽车位置,所以每次用户在屏幕上点击一个新位置时,数据都会被覆盖。
<template>
<div id="app">
<span id="marker" class="fas fa-times" :style=" left: leftCoord, top: topCoord "></span>
<img @click="saveCoordinates($event)" src="./assets/parking-lot.jpg">
</div>
</template>
<script>
import firebase from 'firebase'
const config =
apiKey: 'MY-API-KEY',
authDomain: 'MY-APP.firebaseapp.com',
databaseURL: 'https://MY-APP.firebaseio.com',
projectId: 'MY-APP',
storageBucket: 'MY-APP.appspot.com',
messagingSenderId: '1234567890'
const app = firebase.initializeApp(config)
const db = app.database()
const locationRef = db.ref('location')
export default
name: 'app',
firebase:
location: locationRef
,
mounted ()
this.leftCoord = this.location.leftCoord
this.topCoord = this.location.topCoord
,
data ()
return
leftCoord: '',
topCoord: ''
,
methods:
saveCoordinates: function (clickEvent)
const coordinates =
leftCoord: clickEvent.layerX,
topCoord: clickEvent.layerY
this.location.set(coordinates)
</script>
【问题讨论】:
有些事情我不完全理解:您说“vue 正在尝试在接收到数据之前渲染组件”但是在您共享的代码中没有对 读取数据库,只是一个触发写入的按钮。你能澄清一下吗?究竟是什么问题? 在挂载的钩子中,我尝试使用来自 firebase db 的引用设置标记的左坐标和上坐标,然后将这些更改与标记中的标记中的样式绑定一起应用模板。我收到的最初错误是 .set() 不是函数。 好的,我明白了,感谢您的指点!在挂载的钩子中,如果你这样做console.log(this.location)
会得到什么?
如果你这样做this.leftCoord = locationRef.leftCoord
等一下,我正在寻找解决方案
【参考方案1】:
我添加第二个答案,它不再基于mounted
钩子,而是基于对象绑定的回调函数。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://www.gstatic.com/firebasejs/4.11.0/firebase.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuefire/dist/vuefire.js"></script>
</head>
<body>
<div id="app">
<span id="marker" class="fas fa-times" :style=" left: leftCoord, top: topCoord "></span>
<img @click="saveCoordinates($event)" src="./assets/parking-lot.jpg">
</div>
<script>
var config =
apiKey: ".........",
authDomain: ".........",
databaseURL: ".........",
projectId: ".........",
storageBucket: "........."
;
/* global Vue, firebase */
var db = firebase.initializeApp(config).database()
var todosRef = db.ref('todos')
const locationRef = db.ref('location')
new Vue(
el: '#app',
name: 'app',
firebase:
location:
source: locationRef,
asObject: true,
readyCallback: function ()
this.leftCoord = this.location.leftCoord
this.topCoord = this.location.topCoord
,
data()
return
leftCoord: '',
topCoord: ''
,
methods:
saveCoordinates: function (clickEvent)
console.log(clickEvent.layerX)
const coordinates =
leftCoord: clickEvent.layerX,
topCoord: clickEvent.layerY
locationRef.set(coordinates)
)
</script>
</body>
</html>
【讨论】:
这真是太棒了。感谢您的帮助!【参考方案2】:这样就可以了:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://www.gstatic.com/firebasejs/4.11.0/firebase.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuefire/dist/vuefire.js"></script>
</head>
<body>
<div id="app">
<span id="marker" class="fas fa-times" :style=" left: leftCoord, top: topCoord "></span>
<img @click="saveCoordinates($event)" src="./assets/parking-lot.jpg">
<img @click="readCoords" src="./assets/parking-lot.jpg">
</div>
<script>
var config =
apiKey: ".........",
authDomain: ".........",
databaseURL: ".........",
projectId: ".........",
storageBucket: "........."
;
/* global Vue, firebase */
var db = firebase.initializeApp(config).database()
var todosRef = db.ref('todos')
const locationRef = db.ref('location')
new Vue(
el: '#app',
name: 'app',
firebase:
location:
source: locationRef,
asObject: true
,
mounted()
locationRef.once('value', snapshot =>
this.leftCoord = this.location.leftCoord
this.topCoord = this.location.topCoord
)
,
data()
return
leftCoord: '',
topCoord: ''
,
methods:
saveCoordinates: function (clickEvent)
console.log(clickEvent.layerX)
const coordinates =
leftCoord: clickEvent.layerX,
topCoord: clickEvent.layerY
locationRef.set(coordinates)
,
readCoords: function (clickEvent)
console.log(this.location.leftCoord);
console.log(this.location.topCoord);
)
</script>
</body>
</html>
显然在 vuefire 中没有“本机”方式来等待加载数据的挂载钩子,请参阅https://github.com/vuejs/vuefire/issues/69
我添加了第二个图片链接,其中包含一个新功能 readCoords
,仅用于测试目的。
注意,你也可以在挂载的钩子中做
locationRef.once('value', snapshot =>
this.leftCoord = snapshot.val().leftCoord
this.topCoord = snapshot.val().topCoord
)
【讨论】:
完美!感谢您的帮助! 不客气(我也学到了一些东西:-),这太棒了)【参考方案3】:如果位置是一个对象,你需要像这样绑定:
export default
name: 'app',
firebase:
location:
source: db.ref('location'),
asObject: true,
readyCallback: function ()
,
mounted ()
this.leftCoord = this.location.leftCoord
this.topCoord = this.location.topCoord
,
data ()
return
leftCoord: '',
topCoord: ''
,
methods:
saveCoordinates: function (clickEvent)
const coordinates =
leftCoord: clickEvent.layerX,
topCoord: clickEvent.layerY
this.$firebaseRefs.location.set(coordinates)
注意,设置时,我们需要使用this.$firebaseRefs.location.set(coordinates)
文档https://github.com/vuejs/vuefire
【讨论】:
以上是关于如何使用 vue 和 vuefire 加载 Firebase 数据?的主要内容,如果未能解决你的问题,请参考以下文章
vue + firestore:如何使用 vuefire 绑定/合并数据?
Firebase 和 Vue:如何正确初始化 firebase 和 vuefire?