How to manage dialogs in different router-views? - vue.js

I've got a problem with my vue-router and v-dialogs (vuetify.js components) inside different router-views.
My App.vue looks like this:
<template>
<transition>
<keep-alive>
<router-view/>
</keep-alive>
</transition>
</template>
Inside each router-view I have a component:
<template>
<v-app>
<app-header></app-header>
<v-content></v-content>
<app-footer></app-footer>
<!-- a couple of dialogs here -->
<v-dialog v-model="someData.show"></v-dialog>
<v-dialog v-model="anotherData.show"></v-dialog>
<v-dialog v-model="yetAnotherData.show"></v-dialog>
</v-app>
</template>
When I switch between different router-views and open dialogs overlay shows, but the dialog doesn't. Except for the router-view which was first loaded with the page.
What seems to be the problem? Does is have something to do with the way I define there routes or components?
You check full code over here: https://github.com/websanya/gkp7-app/
Please, help!

In fact I should've used only one v-app outside of router-view in App.vue file.
<template>
<!-- OVER HERE -->
<v-app>
<transition>
<keep-alive>
<router-view/>
</keep-alive>
</transition>
</v-app>
<!-- / OVER HERE -->
</template>
Works like a charm.

Related

Vue transitioning effects disappear when inside a vue slot

I'm having a hard time getting a vue transition to work inside a slot. I should mention I've searched through numerous stackoverflow questions and I haven't seen one that matches my issue. All the ones I've seen so far are talking about <slot> inside the <transition>, eg: vue transition component doesn't work correctly, whereas for me it's the other way round.
There are three vue components, component1, component2 and component3.
component1 has something like:
<template>
<slot name="content">
<slot name="side">
<slot name="default">
</template>
component2 looks something like below:
<component1>
<template #content>Some stuff here</template>
<template #side>Some stuff here</template>
<template #default>
<component3/> #Component3 contains the transition stuff
</template>
</component1>
component3 contains the transition stuff:
<transition
:name="right ? 'slide-right': 'slide-left'"
#before-enter="$emit('before-enter')"
#after-leave="$emit('after-leave')"
>
<div
v-show="$attrs.value"
v-bind="$attrs"
v-on="listeners"
class="u-drawer bg-white"
:class="extraClasses"
:style="getStyles">
<slot v-if="!hideClose" name="close">
<u-button #click="$emit('input', false)"
class="u-drawer-close-button" icon>
<u-icon icon="x" size="1rem" class="mx-auto" />
</u-button>
</slot>
<slot name="default" />
</div>
</transition>
<transition name="fade">
<div v-if="overlay" #click.stop="closeDrawer" v-show="$attrs.value" style="width:100%; height:100%" class="u-overlay"></div>
</transition>
For whatever reason the transition does not work, it's a drawer that is supposed to slide out but it doesn't, instead it just appears instantaneously.
I should mention that, component3 has been used elsewhere in the project where the sliding effect does occur. The only difference here is that it's within a <slot name=default>. Does anyone know what the problem might be?

Vue 3 – <Transition> renders non-element root node that cannot be animated

App.vue has a transition tag to fade the pages out and in.
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in" appear>
<component :is="Component"></component>
</transition>
</router-view>
The Page.vue file has a simple structure, however, it also has a basic sliderjs component which throws the error <Transition> renders non-element root node that cannot be animated. If the transition tag is removed, everything works fine.
<div v-if="page.isReady">
<swiper>
<swiper-slide>Slide 1</swiper-slide>
<swiper-slide>Slide 2</swiper-slide>
<swiper-slide>Slide 3</swiper-slide>
</swiper>
</div>
https://swiperjs.com/vue/
The file also has the following:
import { Swiper, SwiperSlide } from 'swiper/vue';
import 'swiper/swiper.scss';
export default {
components: {
Swiper,
SwiperSlide,
},
setup () {
return {
page: usePage()
}
}
}
Is there any trick to fix the error? Thanks for any tips!
No.
<template>
<div></div>
<div>~someone~</div>
</template>
Yes.
<template>
<div>
  <div></div>
~someone~
</div>
</template>
If you do not use a "div" tag just inside the "Template" tag, you will get the same error. (By the way, it was possible to use other than div tags)
Transitions require single children nodes. Therefore you can wrap the <component> tag inside a <div>, however, a plain <div> inside a <transition> won't trigger the transition, but changing the key attribute does.
We can obtain a unique key by getting the route name:
<router-view v-slot="{ Component, route }">
<transition name="fade" mode="out-in">
<div :key="route.name">
<component :is="Component"></component>
</div>
</transition>
</router-view>
This will effectively transition between routes with a different name, but if you also want to transition between routes of the same name with different parameters, you can use route.fullPath instead of route.name as the key.
I can't fully take credit for this one...but I was having a similar issue and the problem was I had multiple nodes in my view, and found this guy's post on the Vue.js forums:
Found my mistake too. Transition required a single root in components! Since Vue 3 no longer requires a single root node for components I thought this also applies to transitions.
But it’s also logical. CSS requires a single root to which the transitions can refer.
When toggling between elements that have the same tag name, you must tell Vue that they are distinct elements by giving them unique key attributes. Otherwise, Vue’s compiler will only replace the content of the element for efficiency. Even when technically unnecessary though, it’s considered good practice to always key multiple items within a component.
<div>
<router-link to="/"></router-link>
<router-link to="/about"></router-link>
</div>
<router-view v-slot="{ Component, route }">
<transition name="route" :key="route" mode="out-in">
<component :is="Component" />
</transition>
</router-view>
I solved it, it was a minor mistake, there was a character outside a html tag, directly after the tag (comma).
<template>,
<div>
<div>
<swiper>
<swiper-slide>Slide 1</swiper-slide>
<swiper-slide>Slide 2</swiper-slide>
<swiper-slide>Slide 3</swiper-slide>
</swiper>
</div>
</div>
</template>
your dynamic component instance must have a root element.
in you example,'Swiper' and 'SwiperSlide' must have a root element!
don't use RouterView in component parameter of the router. if you need to do that put it inside a root element
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in" appear>
<!-- root element -->
<div>
<component :is="Component"></component>
</div>
</transition>
</router-view>
A solution that worked for me using Nuxt3:
Parent page was:
<template>
<NuxtPage />
</template>
but should be also wrapped into a root node:
<template>
<div>
<NuxtPage />
</div>
</template>
Otherwise I got a transition exception:
Component inside <Transition> renders non-element root node that cannot be animated
I'm doing like this and it works.
<template>
<router-view v-slot="slotProps">
<transition name="route" mode="out-in">
<component :is="slotProps.Component"></component>
</transition>
</router-view>
</template>

Nested Vue router-view transition not reacting when navigating

Here is code example:
https://jsfiddle.net/9jypnkue/
The transition v-on:enter="enter" for the nested view is not called when also the main router-view is transitioning.
<router-view ref="nestedView" v-slot="{ Component }">
<transition v-on:enter="enter">
<component :is="Component"/>
</transition>
</router-view>
I would like both animations being called simultaneously.
Using Vue 3 and Vue Router 4 release candidate/beta.
Adding 'appear' to the router fixes it:
<router-view ref="nestedView" v-slot="{ Component }" appear>
<transition v-on:enter="enter">
<component :is="Component"/>
</transition>
</router-view>
https://jsfiddle.net/27qae5zj/1/

Register multiple Vue components in parent component

I have a global sidebar component TheSidebar.vue:
<template>
<aside>
<slot></slot>
</aside>
</template>
In Blogs.vue (a page component) I try to register two components.
<template>
<div>
<h1>Experiences</h1>
<TheSidebar>
<SearchBlog />
<CategoryCheckboxFilter />
</TheSidebar>
<ExperienceList />
</div>
</template>
It seems like I cannot register two components in a slot?
Is this a good setup anyway and who do I have to achieve this?
Update
It's just working fine now and I can register more than one component in a <slot />. I think some webpack building issue before.

Vue transition works on router-view but not inside component

When I setup a typical route transition everything works as expected
<transition name="view" mode="out-in">
<router-view />
</transition>
But if I try to put the transition inside a view instead, the transition doesn't work
<template>
<transition name="view" mode="out-in">
<main>
<...>
</main>
</transition>
</template>
Any ideas why this could be the case?
The issue, seems to me, is that the <main> element is not entering or leaving, so it doesn't animate. You're probably trying to animate something within the <main> element which does not get targeted by the <transition> pseudo-element.
my suggestion is to encapsulate the element that's being toggled (v-if) or having visibility toggled (v-show) with transition
<template>
<main>
<transition name="view" mode="out-in">
<...something with a v-if or a v-show>
</transition>
</main>
</template>
Also, if you have are using a list/array (v-for) you should use transition-group
docs: https://v2.vuejs.org/v2/guide/transitions.html