首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Vue.js -等待初始页面渲染-然后进行计算

Vue.js -等待初始页面渲染-然后进行计算
EN

Stack Overflow用户
提问于 2019-03-14 18:48:30
回答 2查看 1.9K关注 0票数 0

在Nuxt.js项目中,我有一个页面,在这个页面中,我需要先进行一些客户端计算,然后才能在表中显示一些数据。在计算之前和计算过程中,我想显示一个加载屏幕。

一些背景:数据是农民使用的地块。这张表格应该显示过去几年在一块土地上种植的作物。数据在数据库中的存储方式如下:

代码语言:javascript
复制
plots = [{
  name: 'Plot1',
  year: 2017,
  crop: 'Wheat'
  ...
}, {
  name: 'Plot1',
  year: 2018,
  crop: 'Maize',
  ...
} ...]

在一个方法中,该数据被转换为以下结构的嵌套对象

代码语言:javascript
复制
data = {
  'Plot1': {
    2017: {
      'crop': 'Wheat',
      'catchCrop': true
    },
    2018: {
      'crop': 'Maize',
      'catchCrop': false
    }
  }
  ...
}

并随后显示在表格组件中。

该组件的模型如下所示:

代码语言:javascript
复制
<template>
  <loadingComponent v-if="loading"/>
  <tableComponent v-else-if="!loading && dataAvailable"/>
  <span v-else >No data</span>
</template>
<script>
  data() {
    return {
      loading: true,
      dataAvailable: false
    }
  },
  mounted() {
    this.startCalculation()
  },
  methods: {
    startCalculation() {
      if (store.data) {
        // long running calculation, then
        this.dataAvailable = true
      }
      this.loading = false
    }
  }
</script>

我面临的问题是加载组件从来没有显示出来。但是,startCalculation方法会阻塞用户界面(如果显示了加载组件就可以了),并且只有在计算完成后才会更新组件。

有谁知道我怎么才能绕过这一关吗?提前谢谢你!

编辑:在摆弄之后,我可以通过将setTimeout设置为1ms来让它以我想要的方式工作。这样,加载指示器被显示,数据被正确处理,然后在计算完成后,加载指示器被成功移除。然而,这感觉像是一个非常肮脏的黑客行为,我希望避免它……

代码语言:javascript
复制
mounted() {
  this.loading = true
  // set short timeout in order for Vue to render the loading bar
  setTimeout(() => {
    this.startCalculation()
    this.loading = false
  },1)
}
EN

回答 2

Stack Overflow用户

发布于 2019-03-14 20:46:11

对于上面的代码,您需要使用async/await,因为javascript是异步的,因此行是的,而不是一个接一个地执行。也就是说,如果您的函数被调用,引擎不会等待函数完成其执行,而是并行执行下一行。

因此,当您在函数上使用async await时,这些行将一个接一个地执行。你也可以使用javascript promises.But,如果你要从存储中调用一些方法,那么你也需要在那里添加异步/等待。

如下所示,您可以实现此目标。

代码语言:javascript
复制
async startCalculation() {
      if (store.data) {      
        // long running calculation, then
        await calculationFunction.then(() => {
          this.loading = false
          this.dataAvailable = true
        });
      }
    }
票数 1
EN

Stack Overflow用户

发布于 2019-03-15 06:27:12

我的猜测是也许可以使用

代码语言:javascript
复制
`this.$nextTick().then(...DOM should be re-rendered ... do calculations)`

或者在阻塞之前以async await样式呈现loadingComponent

代码语言:javascript
复制
async function(){
    await this.$nextTick()
    // do calculations sync
    // await do calculations async
    // be happy
}

编辑

另一种选择就是解锁代码。例如,通过搜索找到的第一个vue-worker库:

代码语言:javascript
复制
mounted(){
  this.loading = true;
  async ()=>{
    this.calculatedData= await this.$worker(doBlockingCalculation, ...args);
    this.loading = false;
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55160572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档