如何使用 vue 和 vuefire 加载 firebase 数据?
How do I load firebase data using vue and vuefire?
我不明白有关将 firebase 数据导入 vue 的事情...一旦我得到答案,我很乐意删除问题或辞去我作为程序员的工作 ;)
我知道数据是异步的,因此 vue 试图在接收到数据之前渲染组件。但是,我不知道如何让它等待。示例将不胜感激。我试过阅读文档,但我就是不明白。
这是一个小巧的应用程序,可以显示我们公司的停车场并将用户的点击(汽车)位置保存到 firebase(我们厌倦了忘记我们停在哪里)。感谢您的帮助!
哦,我正在使用 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>
如果location是一个对象,你需要这样绑定:
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)
这样做就可以了:
<!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 中没有 "native" 方式来等待加载数据的挂载挂钩,请参阅 https://github.com/vuejs/vuefire/issues/69
我添加了第二张图片 link 和新功能 readCoords
只是为了测试目的。
注意你也可以在挂载的钩子中做
locationRef.once('value', snapshot => {
this.leftCoord = snapshot.val().leftCoord
this.topCoord = snapshot.val().topCoord
})
我添加第二个答案,它不再基于 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>
我不明白有关将 firebase 数据导入 vue 的事情...一旦我得到答案,我很乐意删除问题或辞去我作为程序员的工作 ;)
我知道数据是异步的,因此 vue 试图在接收到数据之前渲染组件。但是,我不知道如何让它等待。示例将不胜感激。我试过阅读文档,但我就是不明白。
这是一个小巧的应用程序,可以显示我们公司的停车场并将用户的点击(汽车)位置保存到 firebase(我们厌倦了忘记我们停在哪里)。感谢您的帮助!
哦,我正在使用 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>
如果location是一个对象,你需要这样绑定:
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)
这样做就可以了:
<!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 中没有 "native" 方式来等待加载数据的挂载挂钩,请参阅 https://github.com/vuejs/vuefire/issues/69
我添加了第二张图片 link 和新功能 readCoords
只是为了测试目的。
注意你也可以在挂载的钩子中做
locationRef.once('value', snapshot => {
this.leftCoord = snapshot.val().leftCoord
this.topCoord = snapshot.val().topCoord
})
我添加第二个答案,它不再基于 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>