Reputation: 319
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
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
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
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.
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