Reputation: 1647
Recently I design web that user was separated into "user"/"admin" two roles to login.
Different role would login same page but see the different buttons and functions.
MainPage.vue
is the container so I call ajax "/init" to get user info and then commit to Vuex store.
Then Content.vue
is the child page inside MainPage.vue
. It would show different buttons by $store.state.user
message.
However, I would like to call different api in mounted
stage inside Content.vue
according to user's role.
But the role would not be prepared which is commited by ajax called "/init" at this stage.
The overall flow is
// MainContent.vue
beforeCreate: async function () {
await axios.post('/init').then(response => {
if(response && response.data && response.data.data){
this.$store.commit("login", response.data.data)
}
})
}
// Content.vue
mounted: async function() {
try {
console.log(this.$store, this.$store.state.user, this.$store.getters.isAdmin)
// no value here
}
I have check the vue component lifecycle and saw beforeCreate
of parent would be called before mounted
of child.
Would lifecycle methods call in order even they are async function?
How should I solve this problem?
Thanks
Upvotes: 4
Views: 7357
Reputation:
Your component lifecycle will not be a dependable way to handle this case since you're using an async call to fetch the user data. I would suggest displaying a loading state overlay and using mapGetters
to access the store. This will provide a reactive mechanism for you to know when the user data is available. Below is a general idea for a single file component:
computed: {
...mapGetters({
getLoggedInUser: 'GET_LOGGED_IN_USER',
getIsUserAdmin: 'GET_IS_USER_ADMIN',
})
}
....
<template>
<content-overlay v-if="!getLoggedInUser">
Loading...
</content-overlay>
....
<button v-if="getIsUserAdmin">Admin Button</button>
<button v-if="!getIsUserAdmin">Regular User Button</button>
</template>
Upvotes: 1
Reputation:
You could delay the initialization of the Content
component until the user
state becomes available in Vuex by attaching a v-if
directive to the Content
component. Just make sure to initialize user
with null
in the Vuex state.
<!-- MainPage.vue -->
<template>
<Content v-if="$store.state.user" />
</template>
Now this.$store.state.user
and everything that depend on it should be available from Content
component's mounted
lifecycle hook.
Upvotes: 4