当我在 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
文件?
您在组件中正确使用了异步等待。重要的是要了解
async await
不会推迟组件的执行,并且您的组件仍然会渲染并经历不同的生命周期挂钩,例如 mounted
。
async await
所做的是推迟当前上下文的执行,如果您在函数内使用它,await
之后的代码将在承诺解析后发生,在您的情况下,您正在使用它位于 created
生命周期钩子中,这意味着 mounted
生命周期钩子内的代码是一个函数,将在等待后得到解析。
因此,您要做的就是确保仅在收到数据时渲染组件。
具体操作方法如下:
v-if
,然后当数据到来时将 data 设置为 true,如下所示:<SomeComponent v-if="hasData" />
data() {
return {
hasData: false,
}
}
async mounted() {
const users = await fetchUsers()
this.hasData = true;
}
watcher
让您知道组件何时渲染。使用 watch
时你要小心,因为每次发生变化都会发生这种情况。一个简单的经验法则是对不经常更改的变量使用 watch,如果您获取的数据大部分是只读的,您可以使用这些数据,如果不是,您可以向 Vuex 添加一个属性,例如
loadingUsers
.
以下是如何执行此操作的示例:
<SomeComponent v-if="hasData" />
data: {
return {
hasData: false,
}
},
computed: {
isLoading() {
return this.$store.state.app.users;
}
},
watch: {
isLoading(isLoading) {
if (!isLoading) {
this.hasData = true;
}
}
}
如果您要从 API 获取数据,那么最好在 DOM 尚未呈现的地方分派 create 中的操作,但您仍然可以使用“this”而不是 Mounted。如果您使用 Vuex 模块,这里是一个示例:
created() {
this.fetchUsers();
},
methods: {
async fetchUsers() {
await this.$store.dispatch('user/setUsers');
},
},
computed: {
usersGetters() {
// getters here
},
},
问题:您是否希望每次加载应用程序时都运行
await this.setUsers();
(无论显示哪个页面/组件)?
如果是这样,那么你的
App.vue
就可以了。在“用户列表组件”中,也可以使用 mapGetters
来获取值(注意它应该在 compulated 中)。问题是您应该先“等待” setUsers
操作完成,这样组件中的 getUsers
才能有价值。
解决此问题的一个简单方法是使用条件渲染,并且仅在定义
getUsers
时渲染组件。也许您可以将 v-if
添加到“用户列表组件”的父组件中,并且仅在 v-if="getUsers"
为 true 时加载它。那么您安装的逻辑也可以正常工作(因为数据已经存在)。