首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Vue虚拟DOM在进行代价高昂的计算时不会立即更新

Vue虚拟DOM在进行代价高昂的计算时不会立即更新
EN

Stack Overflow用户
提问于 2019-03-17 22:30:57
回答 2查看 319关注 0票数 0

我正在尝试添加一个加载屏幕,当我的应用程序正在对一些数据进行昂贵的哈希和解密时(需要2-3秒)。当我按照应该更新DOM的内容实验性地删除昂贵的部分时,屏幕会立即加载。否则,直到代价高昂的函数完成后,它才会呈现。你知道我搞砸了什么吗?

代码语言:javascript
复制
export default {
  data(){
    return {
      loading: false,
      password: ''
    }
  },
  methods: {
    async unlock(){
      this.loading = true;
      await this.$nextTick()
      // DOM should update, but it doesn't
      try{
        await this.$root.UnlockVaultPassword(this.password);
      } catch(err){
        this.loading = false;
        return;
      }
      // DOM updates once finished with hashing and ciphering
      this.loading = false;
      this.$router.push({name: 'vault'});
    }
  }
}

我在想,因为vue异步地更新dom,所以我遇到了一种竞争条件,在散列中它不能适应dom更新。我怎么能等到dom完成呢?

EN

回答 2

Stack Overflow用户

发布于 2019-03-17 23:18:38

也许可以尝试使用mounted钩子?并在$nextTick之后作为单独的操作调用unlock函数,以便很好地分离关注点。

代码语言:javascript
复制
  mounted () {
    this.loading = true;

    this.$nextTick(function () {
      this.unlock();
    })
  }

  methods: {
    unlock: function() {
      // unlock code
      this.loading = false;
    }
  }

更新:尝试使用一个处理函数,该函数首先在表单提交时设置loading,然后将unlock作为$nextTick的回调函数,如下所示:

代码语言:javascript
复制
  methods: {
    handleFormSubmit: function() {
      this.loading = true;
      this.$nextTick(this.unlock);
    },
    unlock: function() {
      // unlock code
      this.loading = false;
    }
  }

UPDATE 2:如果以上这些都不起作用,那么它听起来就像是$nextTick预期行为中的一个错误,因为在执行以下代码之前,渲染没有完成。如果使用setTimeout强制解锁进程到执行堆栈的末尾,会发生什么情况?

代码语言:javascript
复制
  methods: {
    handleFormSubmit: function() {
      this.loading = true;
      this.$nextTick(() => {
        setTimeout(this.unlock, 0);
      });
    },
    unlock: function() {
      // unlock code
      this.loading = false;
    }
  }
票数 1
EN

Stack Overflow用户

发布于 2019-03-18 00:32:50

所以我找到了一个变通办法...我不喜欢它,但也不是太可怕。我实际上可以把回调推到事件循环上,这样我的哈希只会在渲染完成后发生。

代码语言:javascript
复制
export default {
  data(){
    return {
      loading: false,
      password: ''
    }
  },
  methods: {
    async unlock(){
      this.loading = true;
      setTimeout(() => {
        try{
          await this.$root.UnlockVaultPassword(this.password);
        } catch(err){
          this.loading = false;
          return;
        }
        this.loading = false;
        this.$router.push({name: 'vault'});
      }, 0)
    }
  }
}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55208166

复制
相关文章

相似问题

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