admin管理员组

文章数量:1022784

I am using a layout for my admin pages which brings user informations in a layout, so I don't have to query user information every time the page changes.

However, the problem is, when I query user information in layout, the page does not wait for the layout to load.

myLayout.vue

beforeMount() {
    // getting user info from the server by Vuex action
}

myPage.vue

layout: "myLayout"
...
mounted() {
    // bring user info from the Vuex store
}

In this case, I expect beforeMount to be done in myLayout.vue,

but myPage.vue does not wait and get mounted before Vuex action is pleted.

so the lifecycle would be

layout's beforeMount -> page's beforeMount -> page's mounted -> layout's mounted

because page does not wait for beforeMount of a layout to be done.

Is there a way to prevent a page to be mounted before layout is mounted?

I am using a layout for my admin pages which brings user informations in a layout, so I don't have to query user information every time the page changes.

However, the problem is, when I query user information in layout, the page does not wait for the layout to load.

myLayout.vue

beforeMount() {
    // getting user info from the server by Vuex action
}

myPage.vue

layout: "myLayout"
...
mounted() {
    // bring user info from the Vuex store
}

In this case, I expect beforeMount to be done in myLayout.vue,

but myPage.vue does not wait and get mounted before Vuex action is pleted.

so the lifecycle would be

layout's beforeMount -> page's beforeMount -> page's mounted -> layout's mounted

because page does not wait for beforeMount of a layout to be done.

Is there a way to prevent a page to be mounted before layout is mounted?

Share Improve this question asked Feb 4, 2020 at 8:07 HumbleCoderHumbleCoder 5961 gold badge5 silver badges22 bronze badges 4
  • Problem is not in the order of hook calls. Problem is your async action in Vuex store started in beforeMount. It's not possible to simply wait for async call (promise) in JS - you need to work around it...ie. write all ponents in a way that data is not here on 1st render and will bee available later... – Michal Levý Commented Feb 4, 2020 at 8:38
  • Have you considered nuxtServerInit? is that a possibility for you? – Ohgodwhy Commented Feb 4, 2020 at 8:52
  • @Ohgodwhy the problem is, that I am doing the authentication with middlewares. Therefore, if I use nuxtServerInit to bring user information, it would fail because the authentication is not done yet. If possible, I don't want to rebuild the whole structure. – HumbleCoder Commented Feb 4, 2020 at 10:20
  • i think simple solution is asyncData, you should use this – Mahamudul Hasan Commented Feb 9, 2020 at 2:34
Add a ment  | 

3 Answers 3

Reset to default 2

You can use a middleware on your Layout, that will pretty much run before the layout and therefore, your page.

export default {
  ...
  async middleware({ store }) {
    await store.dispatch('fetch-some-data-with-vuex')
  },
  ...
}

More infos here: https://nuxtjs/docs/2.x/directory-structure/middleware/

This is how I solved it.

The nuxt ponent which renders the page is mounted after the loading is plete. This is achieved using a variable and a conditional statement.

layout.vue

<template>
  <Nuxt v-if="hasLoaded" />
</template>

<script>
export default {
  data () {
    return {
      hasLoaded: false,
    }
  },
  async created () {
    // do stuff

    this.hasLoaded = true;
  },
}
</script>

One way to do this would be :

In your layout ( myLayout.vue ) emit an event after you load your data

this.$root.$emit('layout_loaded', true);

Now you have to listen for this event in your page ( myPage.vue )

mounted(){
    this.$root.$on('layout_loaded', (state) => {
        // bring user info from the Vuex store
    });
}

I am using a layout for my admin pages which brings user informations in a layout, so I don't have to query user information every time the page changes.

However, the problem is, when I query user information in layout, the page does not wait for the layout to load.

myLayout.vue

beforeMount() {
    // getting user info from the server by Vuex action
}

myPage.vue

layout: "myLayout"
...
mounted() {
    // bring user info from the Vuex store
}

In this case, I expect beforeMount to be done in myLayout.vue,

but myPage.vue does not wait and get mounted before Vuex action is pleted.

so the lifecycle would be

layout's beforeMount -> page's beforeMount -> page's mounted -> layout's mounted

because page does not wait for beforeMount of a layout to be done.

Is there a way to prevent a page to be mounted before layout is mounted?

I am using a layout for my admin pages which brings user informations in a layout, so I don't have to query user information every time the page changes.

However, the problem is, when I query user information in layout, the page does not wait for the layout to load.

myLayout.vue

beforeMount() {
    // getting user info from the server by Vuex action
}

myPage.vue

layout: "myLayout"
...
mounted() {
    // bring user info from the Vuex store
}

In this case, I expect beforeMount to be done in myLayout.vue,

but myPage.vue does not wait and get mounted before Vuex action is pleted.

so the lifecycle would be

layout's beforeMount -> page's beforeMount -> page's mounted -> layout's mounted

because page does not wait for beforeMount of a layout to be done.

Is there a way to prevent a page to be mounted before layout is mounted?

Share Improve this question asked Feb 4, 2020 at 8:07 HumbleCoderHumbleCoder 5961 gold badge5 silver badges22 bronze badges 4
  • Problem is not in the order of hook calls. Problem is your async action in Vuex store started in beforeMount. It's not possible to simply wait for async call (promise) in JS - you need to work around it...ie. write all ponents in a way that data is not here on 1st render and will bee available later... – Michal Levý Commented Feb 4, 2020 at 8:38
  • Have you considered nuxtServerInit? is that a possibility for you? – Ohgodwhy Commented Feb 4, 2020 at 8:52
  • @Ohgodwhy the problem is, that I am doing the authentication with middlewares. Therefore, if I use nuxtServerInit to bring user information, it would fail because the authentication is not done yet. If possible, I don't want to rebuild the whole structure. – HumbleCoder Commented Feb 4, 2020 at 10:20
  • i think simple solution is asyncData, you should use this – Mahamudul Hasan Commented Feb 9, 2020 at 2:34
Add a ment  | 

3 Answers 3

Reset to default 2

You can use a middleware on your Layout, that will pretty much run before the layout and therefore, your page.

export default {
  ...
  async middleware({ store }) {
    await store.dispatch('fetch-some-data-with-vuex')
  },
  ...
}

More infos here: https://nuxtjs/docs/2.x/directory-structure/middleware/

This is how I solved it.

The nuxt ponent which renders the page is mounted after the loading is plete. This is achieved using a variable and a conditional statement.

layout.vue

<template>
  <Nuxt v-if="hasLoaded" />
</template>

<script>
export default {
  data () {
    return {
      hasLoaded: false,
    }
  },
  async created () {
    // do stuff

    this.hasLoaded = true;
  },
}
</script>

One way to do this would be :

In your layout ( myLayout.vue ) emit an event after you load your data

this.$root.$emit('layout_loaded', true);

Now you have to listen for this event in your page ( myPage.vue )

mounted(){
    this.$root.$on('layout_loaded', (state) => {
        // bring user info from the Vuex store
    });
}

本文标签: javascriptRender a page after its layout is fully mounted in NuxtStack Overflow