Jakub Kylián
Jakub Kylián

Reputation: 319

Vue3 router + transitions warnings

I have a wrapper component with a transition:

// Wrapper.vue

<template>
  <transition
    appear
    mode="out-in"
    enter-active-class="animate__animated animate__fadeIn animate__faster"
    leave-active-class="animate__animated animate__fadeOut animate__faster"
  >
    <div :key="$route.path">
      <slot />
    </div>
  </transition>
</template>

Then, I populate the default slot with some component from router as follows:

// Page.vue

<template>
  <Wrapper>
    <router-view v-slot="{ Component }">
      <component :is="Component" />
    </router-view>
  </Wrapper>
</template

And I'm getting [Vue Router warn]: <router-view> can no longer be used directly inside <transition> or <keep-alive>. warnings, which seems weird since I'm using the correct syntax imho. Is this intended and if so, what am I missing?

Note: It works properly, I just don't like looking at warnings :)

EDIT: A bit more context - I'm trying to create wrappers for desktop and mobile devices while desktop devices should have the transition described above. The mobile device wrapper is done quite differently and is not relevant here.

Upvotes: 5

Views: 8518

Answers (3)

Mousa Abdelmaksoud
Mousa Abdelmaksoud

Reputation: 31

from the official docs of Vue3, it should be like this:

<router-view v-slot="{ Component }">
    <Transition name="slide-fade">
      <component :is="Component" />
    </Transition>
 </router-view>

The transition name is used in the <style> section like this:

<style>
 .slide-fade-enter-active {
   transition: all 0.3s ease;
}
 .slide-fade-leave-active {
  transition: all 0.1s cubic-bezier(1, 0.5, 0.8, 1);
}
 .slide-fade-enter-from,
 .slide-fade-leave-to {
  transform: translateX(-10px);
   opacity: 0;
 }
</style>

For more info Vue3 Transition

Upvotes: 1

JeremyM4n
JeremyM4n

Reputation: 872

The warning is not supposed to display in this scenario, but only when the "router-view" is the direct child of a "transition" or "keep-alive" component.

The bug has been reported here: https://github.com/vuejs/router/issues/1306

Upvotes: 5

Bubai
Bubai

Reputation: 1240

By official guide you should use <transition> or <keep-alive> inside <RouterView /> and vice-versa not applicable.

<router-view v-slot="{ Component, route }">
  <transition name="fade">
    <component :is="Component" :key="route.path" />
  </transition>
</router-view>

<router-view> exposes a v-slot API mainly to wrap your route components with <transition>, <keep-alive> components.

update:

A computed property may be helpful for this scenario. Tough, I don't know how you've implemented code for small devices. This is one way of doing...

<script>
function isSmallDevice() {
  /*
    code for checking
    device resolution
  */

  return <Boolean>
}

export default {
  computed: {
    setTransitionProperty: function () {
      return isSmallDevice ? '' : 'fade'
    }
  }
}
</script>

<router-view v-slot="{ Component, route }">
  <transition :name="setTransitionProperty" mode="out-in">
    <template #default>
      <component
        :is="Component"
        :key="route.meta.usePathKey ? route.path : undefined"
      />
    </template>
    <template #fallback> Loading... </template>
  </transition>
</router-view>

Another way may be conditional rendering, using v-if, and v-else directives.

Upvotes: 2

Related Questions