简体   繁体   中英

Best way to add single component transitions on page change to nuxt components?

I've tested with CSS/SCSS so far, it seems to work only on first page change:

.page-leave-active {
  .news-item {
    @for $i from 1 through 10 {
      transition-delay: $i * 300ms;
    }
    transform: translateX(115%);
  }
}

I was wondering is there a way to add JS transitions inside a component? Is there an equivalent to mounted , but for unmount ?

if you don't use dynamic page transition name for ssr-nuxt page transition, just add the code in transition attribute like examples in nuxtjs document

if you are using a dynamic page transition name, it's a little hard if you use transition attribute that nuxt provided. I use below code for dynamic page transition name, and it works well for me(don't forget code your own <error-view/> component)

use this instead of <nuxt/> , you can add your logic easily in methods

<template>
    <main>
        <transition
            mode="out-in"
            :name="transitionName"
            @beforeLeave="beforeLeave"
            @enter="enter"
            @afterEnter="afterEnter">
            <router-view v-if="!nuxt.err"/>
            <error-view :error="nuxt.err" v-else/>
        </transition>
    </main>
</template>
<script type="text/javascript">
import Vue from 'vue';
import ErrorView from '@/layouts/error';
export default{
    components: {
        ErrorView
    },
    data() {
        return {
            prevHeight: 0,
            transitionName: 'fade'
        };
    },
    beforeCreate () {
        Vue.util.defineReactive(this, 'nuxt', this.$root.$options.nuxt);
    },
    created() {
        this.$router.beforeEach((to, from, next) => {
            let transitionName = to.meta.transitionName || from.meta.transitionName;
            if (transitionName === 'slide') {
                const toDepth = to.path.split('/').length;
                const fromDepth = from.path.split('/').length;
                transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left';
            }
            this.transitionName = transitionName || 'fade';
            next();
        });
    },
    methods: {
        beforeLeave(el) {
            this.prevHeight = getComputedStyle(el).height;
        },
        enter(el) {
            const { height } = getComputedStyle(el);
            el.style.height = this.prevHeight;
            setTimeout(() => {
                el.style.height = height;
            }, 0);
        },
        afterEnter(el) {
            el.style.height = 'auto';
        }
    }
}
</script>

Here is what you get

在此处输入图像描述

Full resource code of the demo that gif picture shows is here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM