javascript - 如何延迟 'not found' 错误直到数据加载到 Vue.js

标签 javascript vue.js vuejs2

我正在打这条路线:http://site.dev/person/1

我的组件看起来像这样:

// PeopleComponent.vue

<template>

<div>
   <template v-if="person == null">
       <b>Error, person does not exist.</b>
   </template>

   <template v-else>
       <pre> {{ person }} </pre>
   </template>
</div>

</template>

<script>
export default {


    mounted() {
      this.$store.dispatch('getPeople');
    }

    computed: {

      // represents the person whose id potentially matches the value of `/:id` in route.
      person(){ 
          let id = parseInt(this.$route.params.id)
          let person = null

          if(id > 0)
              person = this.$store.state.people.find(p => p.id == id)

          return person;
      }

    }



}
</script>

// [styles]

我在这个组件中做了什么:

I get an ID in my URL. The ID represents a specific resource being shown on this page. I have a person() computed property to retrieve the object whose ID matches the parameter in the URL from my Vuex store.

期望的结果:

At the top of the page, I would like to display an error message if the object cannot be found (if say, for example, someone types an ID that doesn't exist in the array of objects in the store). If the item is found, a simple dump of the object is fine. This currently works, but the delay between fetching the data from the API and finding the right object in the store seems to be just long enough to briefly show the error message as if the object could not be found when the page first loads. When tested with a slower network speed, this error message is visible for several seconds. I want to eliminate it such that it does not appear at all if the object exists.

我尝试过的:

  • v-cloak - 尝试将其应用于每个父 div,甚至是 div#app 本身,但无济于事。我一定是做错了什么。
  • v-if - 如上例所示

不胜感激,谢谢!


2020 年 3 月 31 日更新

根据 Phil 的建议,我尝试加入一个标志来指示页面何时准备就绪。我用两种不同的方式做到了。

方法#1 使 mounted()“异步”并在从我的 API 检索 people 的操作上添加等待。之后将标志设置为 true:

async mounted() { 

  await this.$store.dispatch('getPeople');
  this.loaded = true;

}

但我仍然看到错误消息,很简单。

方法#2

在操作上使用 then 回调,并在回调内将标志设置为 true

mounted() {

  let vm = this

  vm.$store.dispatch('getPeople').then(() => {

      vm.loaded = true;

  })

}

这两种方法都不会阻止消息的出现。

我怀疑这就是正在发生的事情:

核心规则

Error should ONLY show if loaded=true and person=null

  1. 页面加载,loadedfalsepersonnull。错误不会显示。
  2. Page 从 API 调用人员。错误仍然没有显示。
  3. 调用后,loaded 已设置为 true [此时,loadedtrue 并且 person 还没有被计算属性解析,这就是我相信的地方看到错误。]
  4. 计算属性在下一次更新时从存储中找到相关记录。
  5. Person 不再是 null,因此错误消失。

编辑 01/04/2020

回答 Phil 的问题:您的 getPeople() 操作是什么样的?


getPeople({ commit })  {   
        axios.get('/get/people')
        .then(response => {
            commit("getPeople", response.data);
        })
        .catch(error => {
            console.log(error);
        })
},

最佳答案

听起来您还需要一个状态,例如正在加载

将您的 getPeople 操作更改为 composable ,即 返回 Axios Promise 以便它等待异步任务完成...

getPeople ({ commit })  {
  // make sure you return the promise
  return axios.get('/get/people').then(response => {
    commit("getPeople", response.data)
  }).catch(error => {
    console.error(error)
    // also make sure you don't accidentally convert this to a successful response
    return Promise.reject(error)
  })
},

然后尝试这样的事情

export default {
  data: () => ({ loading: true }),
  async created () {
    // "created" fires earlier than "mounted"
    await this.$store.dispatch('getPeople')
    this.loading = false
  },
  computed: {
    // etc
  }
}

现在您可以在模板中使用loading

<div v-if="loading">Loading...</div>
<div v-else>
  <!-- your "person" template stuff goes here -->
</div>

关于javascript - 如何延迟 'not found' 错误直到数据加载到 Vue.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60923431/

相关文章:

javascript - D3 v4 网格 : How do I bind the data properly?

vue.js - 基于视口(viewport)条件渲染NuxtJS组件

webpack - vue.js 应用程序中静态 Assets 的路径

javascript - VueJS路由器中的 `path`和 `fullPath`有什么区别?

javascript - 当开发人员工具关闭时,AngularJS 代码不执行 InternetExplorer

javascript - 如何在 JavaScript 本地存储中逐行存储所有内容?

javascript - ionic 应用程序不会连接到 Socket.IO

javascript - vue-truncate-filter 不过滤并抛出错误

vue.js - Nuxt生成显示错误: Cannot read property 'normalModuleFactory' of undefined

javascript - 如何在 vue.js 中使用 onfocusout 函数?