在 Vuejs 中渲染 DOM 之前,使用路由器中的参数获取 firebase 数据(使用或不使用 vuefire)?

Posted

技术标签:

【中文标题】在 Vuejs 中渲染 DOM 之前,使用路由器中的参数获取 firebase 数据(使用或不使用 vuefire)?【英文标题】:Get firebase data (with or without vuefire) using a parameter from router before DOM renders in Vuejs? 【发布时间】:2020-02-19 06:11:28 【问题描述】:

我正在从另一个视图导航到一个视图并将 itemdId 作为参数值传递给 vue 路由器。

我希望能够使用该 itemId 调用 firebase,以便我可以过滤数据并在 UI 中使用过滤后的结果/数据。我正在使用vuefire

发生的事情是 vue 在 created() 中的数据可用之前开始渲染,我看到错误是控制台说视图正在引用未定义的属性值。

有没有办法在数据可用后渲染视图?

我已经尝试过使用beforeMount 以及createdbeforeCreate 的方法。

见下面的代码:

<h1>projects[0].project_name</h1> //it says type error. cannot read property project_name of undefined. Sometimes on refresh it works but most times it does not. 

脚本代码如下:

    let projectsRef = db.ref('projects');
    export default 
        name: 'ProjectDetailsOpenInvesting',
        props: 
          data: Object
    ,
    firebase:
      projects: projectsRef
    ,
    data()
      return 
        projects:[],
        .....

      
    ,
    created()
      var that = this;
      console.log(this.$route.params.itemid) //this works
      this.projects = this.projects.filter(function(p)
        return p.project_id == that.$route.params.itemid //this works as well
      )
    

Firebase screenshot here

【问题讨论】:

【参考方案1】:

正如您所提到的,一种方法是使用fetch after navigation,即在组件的created 挂钩中获取数据。

要使用vuefire 做到这一点,您需要以编程方式将实时数据库projectsRef Reference 绑定到您的Vue 应用程序中的projects 属性,如下所示:

created()
  console.log(this.$route.params.itemid)
  const itemId = this.$route.params.itemid;
  this.$rtdbBind('projects', projectsRef.orderByKey().equalTo(itemId)).then(projects => 
     this.projects === projects;
  );

如API doc中所述:

$rtdbBind 返回一个 Promise,一旦数据已被解析 检索并同步到状态。

注意需要安装rtdbPlugin插件:https://vuefire.vuejs.org/api/vuefire.html#rtdbplugin


还要注意,我们不是在前端过滤所需的project 项目(使用filter(function(p)return p.project_id == that.$route.params.itemid))),而是在后端,在数据库级别(projectsRef.orderByKey().equalTo(itemId))过滤它,这更高效,避免将整个对象集从后端传输到前端(并避免为此下载量付费,请参阅https://firebase.google.com/pricing?authuser=0)。

【讨论】:

谢谢雷诺。愚蠢的问题:那么我如何访问项目中的数据?我试过 projects.project_name 以及 projects[0].project_name 都返回未定义。如果我做一个 console.log(projects) ;我认为我看到了一个 firebase 对象。如何访问此过滤对象的值? projects[0].project_name 应该可以工作。如果它没有将您的数据库的打印屏幕添加到您的问题中。 刚刚将截图链接添加到问题中。 所以如果查询字符串参数itemid的值例如是12345(意思是console.log(this.$route.params.itemid)应该输出12345)你确实应该做projects[0].project_name 那行得通。非常感谢。路线如下所示: path: '/booked/:itemid', name: 'ProjectDetailsBooked', component: ProjectDetailsBooked, props: true, meta: menuIndex: '1', showTopHeader: true, hideFooter: false 我将 itemId 从一个视图传递到另一个视图,如下所示:router.push(name: 'ProjectDetailsBooked', params: itemid: this.data.project_id);

以上是关于在 Vuejs 中渲染 DOM 之前,使用路由器中的参数获取 firebase 数据(使用或不使用 vuefire)?的主要内容,如果未能解决你的问题,请参考以下文章

VueJS 计算属性未在 DOM 上更新

VueJS - 在渲染子组件之前等待父组件中的更新()

VueJS 在渲染数据之前等待 Apollo

vuejs啥时候使用钩子函数

在 Nuxt.js 中完全呈现路由后运行函数

服务器端渲染(SSR)vuejs 前端项目