如何在VUE生命周期挂钩和VUEX中使用异步/等待?

2022-08-02 00:00:00 vue.js vue-component vuejs2 vuex

当我在mount()生命周期挂钩中的App.vue组件中分派操作时,它在加载其他组件之后运行。我在我的操作中使用了异步/等待并装载了生命周期挂钩。

App.vue文件

methods: {
   ...mapActions({
      setUsers: "setUsers",
   }),
},
async mounted() {
        try {
            await this.setUsers();
        } catch (error) {
            if (error) {
                console.log(error);
            }
        }
    },

action.js文件:

async setUsers(context) {
        try {
            const response = await axios.get('/get-users');
 
            console.log('setting users');
 
            if (response.data.success) {
                context.commit('setUsers', {
                    data: response.data.data,
                });
            }
        } catch (error) {
            if (error) {
                throw error;
            }
        }
    },
在用户列表组件中,我需要从Vuex获取用户。因此,我正在使用mapGetters获取用户列表。

...mapGetters({
            getUsers: "getUsers",
        }),
    mounted() {
            console.log(this.getUsers);
    },

但问题是";设置用户在控制台登录this.getUsers后运行。

在用户列表组件中,我可以在模板中使用getUser,但当我尝试通过控制台登录this.getUser时,它没有提供任何信息。

如何在运行任何其他组件之前运行app.vue文件?


解决方案

您在组件中正确使用了异步等待。重要的是要了解,async await不会延迟组件的执行,并且您的组件仍然会呈现并经历不同的生命周期挂钩,例如mounted

async await所做的是推迟当前上下文的执行,如果您在函数内部使用它,await之后的代码将在Promise解析后发生,在您的情况下,您在created生命周期挂钩中使用它,这意味着mounted生命周期挂钩内的代码将在等待之后解析。

因此,您要做的是确保仅在收到数据时呈现组件。

操作方法如下:

  1. 如果组件是父组件的子组件,可以使用v-if,然后当数据到来时,将data设置为True,如下所示:
数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
data() {
  return {
   hasData: false,
  }
}

async mounted() {
 const users = await fetchUsers()
 this.hasData = true;
}
<SomeComponent v-if="hasData" />

  1. 如果组件不是父组件的子组件,则可以使用watcher通知您组件何时呈现。使用watch时可以小心,因为每次发生更改时都会发生更改。

一个简单的经验法则是将Watch与不经常更改的变量一起使用,如果您获得的数据大多是只读的,您可以使用这些数据,如果不是,您可以向Vuex添加属性,如loadingUsers

这里有一个如何做到这一点的示例:

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
  data: {
    return {
     hasData: false,
    }
  },
  
  computed: {
   isLoading() {
    return this.$store.state.app.users;
   }
  },
  
  watch: {
    isLoading(isLoading) {
      if (!isLoading) {
        this.hasData = true;
      }
    }
  }
<SomeComponent v-if="hasData" />

相关文章