Vue.js page transition fade effect with vue-router

Vue.js page transition fade effect with vue-router

Asked on December 10, 2018 in vue.js.
Add Comment


  • 1 Answer(s)

    Cover <router-view></router-view> with <transition name=”fade”></transition> and add styles:

    .fade-enter-active, .fade-leave-active {
      transition-property: opacity;
      transition-duration: .25s;
    }
     
    .fade-enter-active {
      transition-delay: .25s;
    }
     
    .fade-enter, .fade-leave-active {
      opacity: 0
    }
    

    Brief Solution

    Assume that you have generated your application with vue-cli, example:

    vue init webpack fadetransition
    cd fadetransition
    npm install
    

    Install the router:

    npm i vue-router
    

    Suppose, you are not using vue-cli, so you have to add vue router like this:

    <script src="/path/to/vue.js"></script>
    <script src="/path/to/vue-router.js"></script>
    

    Now CLI has generated backbone apps, where elements can be added;

    1) Create page components

    In Vue, elements can be nested. In your application, a page can be created with standard vue component which is assumed as root to other elements in page.

    Go to src/ -> create pages/ directory. These page-root elements (individual pages) will be put in this directory, while the other elements are used in the original pages can be put to the ready-made elements/ directory.

     

    Create two pages in files known as src/pages/Page1.vue and src/pages/Page2.vue for starters.

    <template>
      <h1>Page 1</h1>
    </template>
     
    <script>
    export default {
    }
    </script>
     
    <style scoped>
    </style>
    

    2) Setup routing

    Edit the src/main.js add the necessary imports:

    import VueRouter from 'vue-router'
    import Page1 from './pages/Page1'
    import Page2 from './pages/Page2'
    

    Add a global router usage:

    Vue.use(VueRouter)
    

    Add a router setup:

    const router = new VueRouter({
      routes: [
        { path: '/page1', component: Page1 },
        { path: '/page2', component: Page2 },
        { path: '/', redirect: '/page1' }
      ]
    })
    

    The previous route just transmits the initial path / to /page1. Edit the application initiation:

    new Vue({
      router,
      el: '#app',
      render: h => h(App)
    })
    

    3) Add a router view

    Set up routing, by place the page elements which is rendered reffering to router is missed. It can be done by using <router-view></router-view> in some place in template like src/App.vue’s <template> tag

     

    4) Add fade transition effect between page components

    Cover the <router-view></router-view> with a <transition name=”fade”> component, e.g.:

    <template>
      <div id="app">
        <transition name="fade">
          <router-view></router-view>
        </transition>
      </div>
    </template>
    

    Vue will create and insert required css classes starts with the specified name in all effect’s duration like fade-enter-active. You can define effects in App.vue’s section:

    <style>
    .fade-enter-active, .fade-leave-active {
      transition-property: opacity;
      transition-duration: .25s;
    }
     
    .fade-enter-active {
      transition-delay: .25s;
    }
     
    .fade-enter, .fade-leave-active {
      opacity: 0
    }
    </style>
    

    That’s it. If you run the app now, e.g. with npm run dev, it will automatically display Page 1 with a fade-in effect. If you rewrite the URL to /page2, it will switch the pages with fade-out and fade-in effects.

     

    5) Optional: Add links to pages.

     

    We can add links for specific pages with the <router-link> element.

     
    <router-link to="/page1">Page 1</router-link>
    <router-link to="/page2">Page 2</router-link>
    

    It automatically gives links with a router-link-active class suppose they are active, but we can specify custom classes suppose you are using Bootstrap

    <router-link class="nav-link" active-class="active" to="/page1">Page 1</router-link>
    <router-link class="nav-link" active-class="active" to="/page2">Page 2</router-link>
    

    Files for reference

    src/main.js:

    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import Vue from 'vue'
    import VueRouter from 'vue-router'
     
    import App from './App'
    import Page1 from './pages/Page1'
    import Page2 from './pages/Page2'
     
    Vue.use(VueRouter)
     
    const router = new VueRouter({
      routes: [
        { path: '/page1', component: Page1 },
        { path: '/page2', component: Page2 },
        { path: '/', redirect: '/page1' }
      ]
    })
     
    /* eslint-disable no-new */
    new Vue({
      router,
      el: '#app',
      render: h => h(App)
    })
    

    src/App.vue:

    <template>
      <div id="app">
        <router-link class="nav-link" active-class="active" to="/page1">Page 1</router-link>
        <router-link class="nav-link" active-class="active" to="/page2">Page 2</router-link>
        <transition name="fade">
          <router-view></router-view>
        </transition>
      </div>
    </template>
     
    <script>
    export default {
      name: 'app'
    }
    </script>
     
    <style>
    .fade-enter-active, .fade-leave-active {
      transition-property: opacity;
      transition-duration: .25s;
    }
     
    .fade-enter-active {
      transition-delay: .25s;
    }
     
    .fade-enter, .fade-leave-active {
      opacity: 0
    }
    </style>
    

    src/pages/Page1.vue:        

    <template>
      <h1>Page 1</h1>
    </template>
     
    <script>
    export default {
    }
    </script>
     
    <style scoped>
    </style>
    

    src/pages/Page2.vue:         

    <template>
      <h1>Page 2</h1>
    </template>
     
    <script>
    export default {
    }
    </script>
     
    <style scoped>
    </style>
    
    Answered on December 10, 2018.
    Add Comment


  • Your Answer

    By posting your answer, you agree to the privacy policy and terms of service.