ktquez / vue-extend-layout

Default layout or create custom layouts for the pages of your Vue.js SPA (Multiple layouts)
https://vue-layouts2.surge.sh/
MIT License
131 stars 16 forks source link

Hello #6

Closed ArtStepanyuk closed 6 years ago

ArtStepanyuk commented 6 years ago

Thanks for a nice lib, I have a found a bug tho

I have defined a default layout for most of the application and login layout

So the bug is following even if I got to route with the log in it tries to render default one for the second so i see a blinking of navbar which I have on default and don't have on login page.

I could obviusly just change login route to be default to avoid this one but I'd like to know if there is any other options.

Thank you

ktquez commented 6 years ago

Thanks for use! How are you doing? You can show your code?

ArtStepanyuk commented 6 years ago

Sure sorry for taking a while to respond

I have a default layout defined like this

<template>
  <div class="page-container">
    <md-app
      md-waterfall
      md-mode="fixed">
      <!-- header -->
      <md-app-toolbar class="md-primary flex-container">
        <div class="logo-wrapper">
          <md-button
            class="md-icon-button"
            @click="menuVisible = !menuVisible">
            <md-icon>menu</md-icon>
          </md-button>

          <md-avatar>
            <img src="../../static/logo.jpg">
          </md-avatar>
        </div>

        <div class="user-info-wrapper">
          <md-button class="md-fab md-mini">
            <md-avatar class="md-avatar-icon md-accent">{{ userCredentials }}</md-avatar>
          </md-button>
          <md-button
            class="md-fab md-mini"
            @click="openLogOutModal = !openLogOutModal">
            <md-icon>exit_to_app</md-icon>
          </md-button>
        </div>
      </md-app-toolbar>

      <md-app-drawer :md-active.sync="menuVisible">
        <sidebar/>
      </md-app-drawer>

      <md-app-content class="main-content-wrapper">

        <router-view v-transition/>
      </md-app-content>
    </md-app>

    <!-- Logout modal -->
    <md-dialog-confirm
      :md-active.sync="openLogOutModal"
      md-title="Logout"
      md-content="Are you sure you want to log out?"
      md-confirm-text="Agree"
      md-cancel-text="Disagree"
      @md-confirm="logOut" />
  </div>
</template>

And my login layout which is

<template>
  <router-view v-transition/>
</template>

Routes look like this

export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/login',
      name: 'Login',
      component: () => import('@/components/Login'),
      meta: {
        layout: 'LayoutLogin' // name of the layout
      }
    },
    {
      path: '/',
      name: 'InformationPortal',
      meta: { loggedIn: true },
      component: InformationPortal
    }

So the issue looks like this every time when I try to load login layout first it blinksfor a second and shows header which you can see in default layout

ktquez commented 6 years ago

Can you publish a demo? Can be a temporary page on surge.sh host

ggedde commented 6 years ago

I am getting the same issue.
Though it is only on first page load. When navigating around things work fine, but if I go directly to a specific component in the URL that is not the default Layout it will first load the default layout until the component is ready then it switches to the defined layout for that component.

An example is if I use beforeRouteEnter on a component. My component is Post and the route is /post/:id. Here is my beforeRouteEnter code on the component

beforeRouteEnter (to, from, next) {
        axios.get('https://jsonplaceholder.typicode.com/posts/5').then((response) => {
            next((vm) => {
                vm.post = response.data
            })
        })
    },

Everything works fine when I first go to my Application and then navigate to /post/5. However, if I copy the url and paste it into a new tab it will load the default layout first then load the posts layout after beforeRouteEnter has completed.

ktquez commented 6 years ago

@ggedde @ArtStepanyuk I understand now. I I'll take a look and resolve this case later this week.

Thanks for using.

ArtStepanyuk commented 6 years ago

Sorry that i wasn't able to put demo lately got quite busy myself I also use a hook for router.beforeEach hope this will help

ktquez commented 6 years ago

@ArtStepanyuk No problem, I'll do some tests and this week I will release a new version with this problem fixed. Thanks

ggedde commented 6 years ago

@ArtStepanyuk Thanks Alan, However, before you update it I think there might be a better solution.

While this might be a bug I am now starting to think that this is a good thing and could be an awesome feature with some tweaks.

Let's say my component uses beforeRouteEnter and takes 2-10 seconds to resolve. I wouldn't really want to show my users a blank screen until it resolves and therefore I would want to give them some sort of Layout until fully resolved. However, I wouldn't want it to be 'default'. I would prefer 'loading' where I can give them a nice loader gif or something.

Technically, I could do this now and just make my 'default' the loader screen and assign 'panel' and 'login' to all my routes, but that would be tedious since 95% would be 'panel'.

So here is my suggestion: Make an option when registering VueExtendLayout to set a loaderLayout (default = '') I would also like to be able to set a defaultLayout (default = 'default') While we are at it I would also like a layoutsDir (default = '@/layouts')

Ex.

Vue.use(VueExtendLayout, {
    loaderLayout: 'loader',
    defaultLayout: 'panel',
    layoutsDir: '@/app/layouts'
})

Feel free to use whatever names you want. This is just my suggestion. Also by using the Vue.use Options it wont interfere with anybody currently using the plugin as the defaults would work as it does now.

PS an easy way to test beforeRouteEnter is to just use a setTimeout

beforeRouteEnter (to, from, next) {
    setTimeout(() => {
        next()
    }, 3000)
},
ktquez commented 6 years ago

@ggedde Awesome ideas, I'll definitely try them out. Thanks

ktquez commented 6 years ago

@ggedde @ArtStepanyuk Done: v1.1.0 https://github.com/ktquez/vue-extend-layout#options

Thanks so much for use and for contribution.

ktquez commented 6 years ago

@ggedde About customizing the layout directory, it is still not working, because I use require.context and it only accepts the static literal and nothing dynamic. https://webpack.js.org/guides/dependency-management/#require-context

But I'll do other future tests and see a way to make it work.

ktquez commented 6 years ago

This page is currently delayed 5 second: https://vue-layouts.surge.sh/contact