Role-based applications could load different layouts based on the user's role. Currently, I am utilizing the layout property in every component like:
layout(context) {
return context.store.state.auth.user.role
}
my layout folder is structured like:
layout/
Which works great until I create a new component and forget to throw this snippet in.
I am wondering if having a global method to set the default layout would be a useful feature. In the scenario of programmatically changing the layout based on a user's role, I would image it would be called like:
this.$layout.setDefault(this.$auth.user.role + '.vue'); // admin role -> admin.vue
// or maybe even bind it?!
this.$layout = this.$auth.user.role + '.vue';
Maybe I am overthinking this. Thanks!
I think that's already possible:
$nuxt.setLayout('admin')
You could just watch the store.state.auth.user.role
and change layout.
Thank you! Do you know of any way I can access this.$nuxt from within vuex?
@russellsean on client-side: window.$nuxt
.
PS: Closing here as the requested feature is already included.
I noticed this only changes for the current component. If you route to another page it changes back to the default layout. Is there any way to change the default layout for the entire app?
Jumping in here, is there a way to use setLayout from inside asyncData?
All I found is accessing context.app.methods.setLayout
but it doesn't change the actual layout of the printed page.
@russellsean @altryne did you find the solution?
@marko-mlinarevic negative. I took a different approach. I use the same layout for authenticated users, but load components based on their role.
@russellsean I did a hacky solution.
when landing on page I do this in fetch
beforeNuxtRender(({ nuxtState }) => {
nuxtState.layout = store.state.layout;
})
and when changing pages I do this in created
this.$nuxt.setLayout(this.$store.state.layout)
It works for now
Hi guys the solution on the client works very well, just need a loading to cover the layout changes, but in the fetch
the solution for the backend works but throws some errors on the console about the Virtual DOM, is there another solution to resolve in the serve side? Because I think is a feature that the dev wanted to them.
Maybe my approach can help.
In default.vue layout I placed the layout change in the data().
You can place the layout switching logic in each layout.
data() {
if(this.$auth.loggedIn) {
this.$nuxt.setLayout('different-layout');
}
}
Clunky but works better than $nuxt.setLayout since it works through context and seems to have no delay on the rendering.
context.route.matched[0].components.default.options.layout = "admin"
The proposed $nuxt.setLayout
unfortunately does not immediatly work through middleware. It only works inside a timeout with 0 ms delay but then the switch is visible to the user.
Most helpful comment
I think that's already possible:
You could just watch the
store.state.auth.user.role
and change layout.