如何在 vue 生命周期挂钩中使用 async/await 和 vuex?

Rob*_*bin 8 vue.js vue-component vuex vuejs2

当我在 Mounted() 生命周期挂钩中的 App.vue 组件中分派一个操作时,它会在其他组件加载后运行。我在操作中使用 async/await 并安装了生命周期挂钩。

应用程序.vue 文件

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

动作.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;
            }
        }
    },
Run Code Online (Sandbox Code Playgroud)

在用户列表组件中,我需要从 vuex 获取用户。所以我使用 mapGetters 来获取用户列表。

...mapGetters({
            getUsers: "getUsers",
        }),
    mounted() {
            console.log(this.getUsers);
    },
Run Code Online (Sandbox Code Playgroud)

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

在用户列表组件中,我可以在模板中使用getUsers ,但是当我尝试控制台记录this.getUsers时,它什么也没有给出。

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

小智 18

您在组件中正确使用 async wait 。重要的是要了解这async await不会推迟组件的执行,并且您的组件仍将呈现并经历不同的生命周期挂钩,例如mounted.

所做async await的是推迟当前 context的执行,如果您在函数内使用它,则await在 Promise 解析后将发生后面的代码,并且在您的情况下,您在生命周期挂钩中使用它created,这意味着生命周期钩子内的代码mounted是一个函数,将在等待后得到解决。

因此,您要做的就是确保仅在收到数据时才渲染组件。

操作方法如下:

  1. 如果该组件是父组件的子组件,则可以使用v-if,然后当数据到来时将 data 设置为 true,如下所示:

data() {
  return {
   hasData: false,
  }
}

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

  1. 如果组件不是父组件的子组件,您可以使用 awatcher让您知道组件何时呈现。使用时watch要小心,因为每次发生变化都会发生这种情况。

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

以下是如何执行此操作的示例:

  data: {
    return {
     hasData: false,
    }
  },
  
  computed: {
   isLoading() {
    return this.$store.state.app.users;
   }
  },
  
  watch: {
    isLoading(isLoading) {
      if (!isLoading) {
        this.hasData = true;
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)
<SomeComponent v-if="hasData" />
Run Code Online (Sandbox Code Playgroud)


小智 0

问题:您是否希望每次加载应用程序时都运行await this.setUsers();(无论显示哪个页面/组件)?

如果是这样,那么你的App.vue就很好。在您的“用户列表组件”中,也可以使用它mapGetters来获取值(注意它应该在计算中)。问题是您应该setUsers首先“等待”操作完成,这样您的getUsers组件才能有价值。

解决此问题的一个简单方法是使用条件渲染getUsers,并且仅在定义时渲染组件。也许您可以将 a 添加v-if到“用户列表组件”的父组件中,并且仅在v-if="getUsers"为 true 时加载它。那么您安装的逻辑也可以正常工作(因为数据已经存在)。