【问题标题】:How to use async/await in vue lifecycle hooks with vuex?如何在带有 vuex 的 vue 生命周期钩子中使用 async/await?
【发布时间】:2021-04-14 19:03:20
【问题描述】:

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

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 之后运行“设置用户”控制台登录。

在用户列表组件中,我可以在模板中使用 getUsers,但是当我尝试控制台日志 this.getUsers 时,它什么也没提供。

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

【问题讨论】:

    标签: vue.js vuejs2 vue-component vuex


    【解决方案1】:

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

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

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

    这是怎么做的:

    1. 如果组件是父组件的子组件,可以使用v-if,然后数据来的时候设置数据为true,像这样:

    data() {
      return {
       hasData: false,
      }
    }
    
    async mounted() {
     const users = await fetchUsers()
     this.hasData = true;
    }
    <SomeComponent v-if="hasData" />
    1. 如果组件不是父组件的子组件,您可以使用watcher 让您知道组件何时渲染。使用watch 时要小心,因为每次更改都会发生。

    一个简单的经验法则是使用 watch 和不经常变化的变量,如果你得到的数据大部分是只读的,你可以使用数据,如果不是,你可以向 Vuex 添加一个属性,例如 @ 987654332@.

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

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

    【讨论】:

      【解决方案2】:

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

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

      解决此问题的一种简单方法是使用Conditional Rendering,并且仅在定义getUsers 时呈现组件。可能您可以将v-if 添加到“用户列表组件”的父组件中,并且仅在v-if="getUsers" 为真时加载它。然后你的挂载逻辑也可以正常工作(因为数据已经存在)。

      【讨论】:

        【解决方案3】:

        如果您从 API 获取数据,那么最好在尚未渲染 DOM 的 created 内部调度操作,但您仍然可以使用“this”而不是 mount。如果您正在使用 Vuex 模块,以下是一个示例:

        created() {
          this.fetchUsers();
        },
        methods: {
          async fetchUsers() {
            await this.$store.dispatch('user/setUsers');
          },
        },
        computed: {
          usersGetters() {
            // getters here
          },
        },
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-10-21
          • 2022-12-13
          • 2021-11-10
          • 1970-01-01
          • 2019-01-18
          • 2019-04-12
          • 2018-04-23
          • 2018-11-18
          相关资源
          最近更新 更多