【问题标题】:How do I load firebase data using vue and vuefire?如何使用 vue 和 vuefire 加载 Firebase 数据?
【发布时间】: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
  • 等一下,我正在寻找解决方案

标签: firebase firebase-realtime-database vue.js vuefire


【解决方案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

【讨论】:

    猜你喜欢
    • 2020-09-25
    • 2018-03-12
    • 2017-07-31
    • 2021-06-23
    • 2017-11-15
    • 2018-04-14
    • 2018-08-23
    • 1970-01-01
    • 2019-02-13
    相关资源
    最近更新 更多