繁体   English   中英

在 Vue 上 mount() 之前从 firebase 获取数据

[英]Fetching data from firebase before mounted() on Vue

我试图在调用 mount() 钩子之前从 firebase 获取数据,但 firebase 查询是异步函数,我正在努力处理这些。 这是我的代码片段:

<template>
  <b-table-simple sticky-header="90%" class="table-bordered">
    <b-thead head-variant="dark">
      <b-tr>
        <b-th >氏名</b-th>
        <b-th v-for="date in printables" :key="date" class="text-center" v-html="date"></b-th>
      </b-tr>
    </b-thead>
    <b-tbody v-if="fetched">
      <template v-for="(staff_data, staff_id) in project.assigned_staff">
        <b-tr :key="staff_id">
          <b-th rowspan="6">
            <b-tr>
              <b-th rowspan="6" v-html="staff_data.name.split(/ | /).join('<br>')"></b-th>
              <b-th >[]</b-th>
            </b-tr>
            <b-tr>
              <b-th >出勤</b-th>
            </b-tr>
            <b-tr>
              <b-th >残業</b-th>
            </b-tr>
            <b-tr>
              <b-th >深夜</b-th>
            </b-tr>
            <b-tr>
              <b-th >内容</b-th>
            </b-tr>
            <b-tr>
              <b-th >弁当</b-th>
            </b-tr>
          </b-th>
          <b-td v-for="i in days.length" :key="i">
            <b-form-checkbox @change.native="setBGColor($event)" :ref="`select-${i}`"></b-form-checkbox>
          </b-td>
        </b-tr>
        <b-tr :key="staff_id">
          <b-td v-for="day in days" :key="day">
            <b-form-select @change.native="setBGColor($event)" :ref="`regular-${staff_id}-${day}`" :options="regularTimeOption"></b-form-select>
          </b-td>
        </b-tr>
        <b-tr :key="staff_id">
          <b-td v-for="day in days" :key="day">
            <b-form-select @change.native="setBGColor($event)" :ref="`overtime-${staff_id}-${day}`" :options="overTimeAndLateNightOption"></b-form-select>
          </b-td>
        </b-tr>
        <b-tr :key="staff_id">
          <b-td v-for="day in days" :key="day">
            <b-form-select @change.native="setBGColor($event)" :ref="`latenight-${staff_id}-${day}`" :options="overTimeAndLateNightOption"></b-form-select>
          </b-td>
        </b-tr>
        <b-tr :key="staff_id">
          <b-td v-for="day in days" :key="day">
            <b-form-select @change.native="setBGColor($event)" :ref="`type-${staff_id}-${day}`" :options="typeOption"></b-form-select>
          </b-td>
        </b-tr>
        <b-tr :key="staff_id">
          <b-td v-for="day in days" :key="day">
            <b-form-select @change.native="setBGColor($event)" :ref="`bento-${staff_id}-${day}`" :options="bentoOption"></b-form-select>
          </b-td>
        </b-tr>
      </template>
    </b-tbody>
  </b-table-simple>
<template>
//... 

const project

export default {
 beforeCreate() {
  // fetching "project" which is necessary to determine table structure (laying out <b-tr>, <b-th> and <b-td>)
  // this should be done before "mounted()" hook
  firebase.database().ref(`/project/${projectId}`)
                     .once('value')
                     .then(...)
  // fetching "daily_report" which is data to fill each <b-td>
  // this should be executed after "project" is fetched
  firebase.database().ref(`/daily_report/${projectId}`)
                     .once('value')
                     .then(snapShot => {
                       project = snapShot.val()                 
                       ...
                     })
 },
 mounted() {
   const elRegular = this.$refs[`regular-${postfix}`]
   elRegular.value = report.hours_regular
 },
 //...
}

对我来说理想的顺序是:

  • beforeCreate() 启动
  • 抓取项目启动
  • 抓取项目完成
  • 获取daily_report 已启动
  • 获取daily_report 已完成
  • beforeCreate() 完成
  • 所有 , 和 都在 created() 和 mount() 之间呈现
  • 已安装()启动
  • 所有这些都充满了来自daily_report的数据
  • 安装()完成

但是因为 firebase.database().on() 和 once() 是异步函数,实际顺序是:

  • beforeCreate() 启动
  • 抓取项目启动
  • 获取 daily_report 已启动
  • beforeCreate() 完成
  • 已安装()启动
  • 安装()完成
  • 抓取项目完成
  • 获取daily_report 已完成

我认为这里最大的问题是在 mount() 启动后获取完成的项目。 我搜索了 vue 路由器的 async/await 和 beforeRouteEnter 守卫,但似乎没有一个能解决我的问题。 如何在启动挂载钩子之前完成基于承诺的功能?

您应该将其添加到组件的data部分,而不是使用外部变量。 这样,Vue 就可以在异步调用 Firebase 之后使用它。

export default {
 data() {
  project: {
   // An empty array so Vue start with no lines,
   // and add them once the array is populated.
   assigned_staff: []
 },
 beforeCreate() {
  // fetching "project" which is necessary to determine table structure
  // (laying out <b-tr>, <b-th> and <b-td>)
  // this should be done before "mounted()" hook
  firebase.database().ref(`/project/${projectId}`)
                     .once('value')
                     .then(...)
  // fetching "daily_report" which is data to fill each <b-td>
  // this should be executed after "project" is fetched
  firebase.database().ref(`/daily_report/${projectId}`)
                     .once('value')
                     .then(snapShot => {

                       // Set the property 'project' of the commponent
                       // to the value of the snapshot
                       this.$set(this, 'project', snapShot.val());

                       ...
                     })
 },
 mounted() {
   const elRegular = this.$refs[`regular-${postfix}`]
   elRegular.value = report.hours_regular
 },
 ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM