Transitions not working on nuxt-child component when route changes - vue.js

I want to create a very simple nuxt transition between child routes.
The structure is:
index.vue
index
--one.vue
--two.vue
--three.vue
index.vue:
<template>
<div>
<nuxt-link to="/one">one</nuxt-link>
<nuxt-link to="/two">two</nuxt-link>
<nuxt-link to="/three">three</nuxt-link>
<nuxt-child :key="$route.fullPath"></nuxt-child>
</div>
</template>
<script>
export default {
transition: 'fade',
data(){
return {
}
},
}
</script>
<style scoped>
.fade-enter-active, .fade-leave-active{
transition: all 1s;
}
.fade-enter, .fade-leave-to{
opacity: 0;
}
.fade-leave, .fade-enter-to{
opacity: 1;
}
</style>
The child components:
one.vue:
<template>
<div>
1
</div>
</template>
two.vue
<template>
<div>
2
</div>
</template>
three.vue
<template>
<div>
3
</div>
</template>
The problem is:
that nothing happens! when I change routes, they change in a way like there is no transition.
what I have done:
I tried to do exactly what the nuxt document has said.
Also I searched a lot about it, but unfortunately, none of the similar questions have been answered.
question1
question2
question3

Related

How to modify src attribute in image to make many cards VueJS

I want to have many card from my component and I want to change the src attribute on every image. Please help me to do it. Thankyou :D
<!---THIS IS MY PAGE FILE---->
<template>
<div>
<class-list :src="image1"></class-list>
<class-list :src="image2"></class-list>
<class-list :src="image3"></class-list>
<class-list :src="image4"></class-list>
</div>
</template>
<!---THIS IS MY COMPONENT FILE---->
<template>
<div>
<a-card hoverable style="width: 240px">
<img
slot="cover"
alt="example"
:src="image"
/>
<a-card-meta title="Europe Street beat">
<template slot="description">
www.instagram.com
</template>
</a-card-meta>
</a-card>
</div>
</template>
This kind of code should solve your use-case, here is a SFC link.
page
<template>
<div v-for="image in images">
<card :image="image"></card>
</div>
</template>
<script>
import Card from './Card.vue'
export default {
components: { Card },
data() {
return {
images: ['https://images.pexels.com/photos/5044497/pexels-photo-5044497.jpeg', 'https://images.pexels.com/photos/9365604/pexels-photo-9365604.jpeg', 'https://images.pexels.com/photos/10392192/pexels-photo-10392192.jpeg']
}
}
}
</script>
Card.vue
<template>
<div>
<img slot="cover" alt="example" :src="image" />
</div>
</template>
<script>
export default {
props: ['image']
}
</script>
<style scoped>
img {
width: 200px;
}
</style>
Here is the end result

Why does this Vue3 transition break data binding?

I have this issue I've been hitting for hours now; I can't understand why it doesn't work as expected.
I pasted an example code below. The issue is that when editing the name, {{name}} is not updated. However, if I remove either of the <transition> element or the v-if="show" condition, then data binding works as expected. Same if the {{name}} is placed outside the transition.
So it seems the transition blocks data binding? However I don't find anything about it in the docs or elsewere. I tested this code in a Vue2 playground, and it works as expected (data binding works). So the behavior seems to depend on Vue3.
Is there something I'm missing? Is it a bug in Vue3?
Thanks in advance for any input or idea.
<template>
<div id="demo">
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<div v-if="show">
<p>hello, {{name}}</p>
<input v-model="name" type="text" />
</div>
</transition>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
data() {
return {
name: "",
show: true,
}
}
});
</script>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.8s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
It works just fine in plain JS...
So try to focus on the differences:
TypeScript (i cannot use it here on SO) - I really doubt its the cause but you can try
Scoped CSS - did you tried to remove scoped ? There are some issues with scoped CSS and <transition>. Check this issue in Vue-loader. My example is not build with Webpack so Vue-loader is not used but it's for sure used in your project...
const app = Vue.createApp({
data() {
return {
name: "",
show: true,
}
},
template: `
<div id="demo">
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<div v-if="show">
<p>hello, {{name}}</p>
<input v-model="name" type="text" />
</div>
</transition>
</div>
`
}).mount("#app");
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.8s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.0/vue.global.js"></script>
<div id="app"></div>
I meet same question, you can try to set the initial value of 'show' to false and at the lifeCycle to modify 'show' for true.

Nuxt.js - How to have separate layout?

In my default layout I have header and footer for every page. But in error pages I need a full page without header and footer. So I made another layout and I'm calling it in the export default section. But it's still have header and footer.
default.vue
<template>
<div>
<app-header></app-header>
<nuxt />
<app-footer></app-footer>
</div>
</template>
<script>
import Header from '~/components/Header.vue'
import Footer from '~/components/Footer.vue'
export default {
components: {
'app-header': Header,
'app-footer': Footer,
}
}
</script>
error.vue
<template>
<div class="container">
<h1 v-if="error.statusCode === 404">Page not found</h1>
<h1 v-else>An error occurred</h1>
<nuxt-link to="/">Home page</nuxt-link>
</div>
</template>
<script>
export default {
props: ['error'],
layout: 'fullpage' // you can set a custom layout for the error page
}
</script>
fullpage.vue
<template>
<div>
<nuxt />
</div>
</template>
Where I'm wrong?
You can do like this
1 - create a layouterror.vue file inside layouts folder (Put nothing inside just the basic code).
<template>
<div>
</div>
</template>
<script>
export default {}
</script>
<style>
</style>
2 - create a error.vue file inside layouts folder.
3 - and pass your error file a layout like this =>
export default {
layout: 'layouterror'
}
Maybe its help
Thanks !
ON Your Nuxt Project Folder called layouts, Create a file named error.vue and it will automatically detect all your 404 error which is page not found.
error.vue
<template>
<div class="error-page">
<h1>Oops, something went wrong!</h1>
<p>Back to safety!</p>
</div>
</template>
<style scoped>
.error-page {
text-align: center;
}
.error-page a {
text-decoration: none;
color: red;
}
.error-page a:hover,
.error-page a:active {
color: salmon;
}
</style>

vue.js:597 [Vue warn]: $listeners is readonly router-link

I´m using vue.js to build application and i am stuck with this warning that affects all my app router-links apparently.
I know that this may be due to multiple vue instances op but i already checked and i don´t know where it may be!
Sidenav.vue
<template>
<section id="sidenav">
<router-link to="/" tag="button" class="uk-button uk-button-default uk-button-large uk-width-1-1
uk-margin-small-bottom" active-class="uk-button-primary" exact> Home </router-link>
<router-link to="/sistema" tag="button" class="uk-button uk-button-default uk-button-large uk-width-1-1
uk-margin-small-bottom" active-class="uk-button-primary"> Gestão de Sistema </router-link>
<router-link to="/consumo" tag="button" class="uk-button uk-button-default uk-button-large uk-width-1-1
uk-margin-small-bottom" active-class="uk-button-primary"> Pontos de Consumo </router-link>
<router-link to="/controlo" tag="button" class="uk-button uk-button-default uk-button-large uk-width-1-1"
active-class="uk-button-primary">
Controlo</router-link>
</section>
</template>
<script>
export default ({
});
</script>
<style>
</style>
Here is the warning that affects my app:
vue.js:597 [Vue warn]: $listeners is readonly.
found in
---> <RouterLink>
<AppSidenav> at src/components/Sidenav.vue
<App> at src/App.vue
<Root>
App.vue
<template>
<div id="app">
<div class="uk-container" style="margin-top:10px;" v-if="checkLogin()">
<app-header></app-header>
<div class="uk-grid my-grid">
<div class="uk-width-1-4 my-nav">
<app-sidenav></app-sidenav>
</div>
<div class="uk-width-3-4" style="border-left:1px solid #e5e5e5; padding-top: 10px;">
<router-view></router-view>
</div>
</div>
<app-footer></app-footer>
</div>
<app-login v-else></app-login>
</div>
</template>
<script>
import Header from './components/Header';
import Sidenav from './components/Sidenav';
import Home from './components/Home';
import Footer from './components/Footer';
import Login from './components/login/Login';
import {mapGetters} from 'vuex';
export default {
components: {
'appHeader': Header,
'appSidenav': Sidenav,
'appHome': Home,
'appFooter': Footer,
'appLogin': Login,
},
computed: {
checkLogin() {
return this.isLoggedIn;
}
},
methods:{
...mapGetters(['isLoggedIn']),
},
}
</script>
<style>
.my-grid{
border-top:1px solid #e5e5e5;
margin-top: 10px !important;
}
.my-nav{
padding: 20px 10px 20px 10px;
/*padding-top: 50px;*/
/*padding-bottom: 20px;*/
border-bottom: 1px solid #e5e5e5;
/*padding-left:10px;*/
/*padding-right:10px;*/
/*background-color: #F0F0F0;*/
}
</style>
I have routes.js and store.js where i import vue and use Router and Vuex respectively inside both files.
Found the issue, i am using vue package through npm but i was also importing vue in my index.html file!
Just removed it and everthing is fine now!

Vue 2 Transition not working

I have no idea where my code went wrong. It should be a simple transition. When I click the button the message shows correctly, but just that the there is no fade transition happening at all.
<template>
<div>
<transition name="fade">
<message v-show="showMessage" class="tr pop-up-message">
<p slot="header">This is Header</p>
<span slot="body">This is Body</span>
</message>
</transition>
<div v-if="!showMessage" class="block" #click.prevent="showMessage = true">
<a class="button is-primary">Primary</a>
</div>
<div v-else-if="showMessage" class="block" #click.prevent="showMessage = false">
<a class="button is-primary">Primary</a>
</div>
</div>
</template>
<script>
import message from './Message.vue'
export default {
components:{
'message': message,
},
data(){
return{
showMessage: false
}
},
}
</script>
Have you added these CSS as well:
.fade-enter-active, .fade-leave-active {
transition: opacity .5s
}
.fade-enter, .fade-leave-to /* .fade-leave-active in <2.1.8 */ {
opacity: 0
}
I have tried to reproduce your code here with above CSS which works.
I had two <p> tags right next to each other like below
<p v-if="!isControlling">Take control of the camera by clicking</p>
<p v-else>Press <kbd>Esc</kbd> to exit camera. <kbd>W</kbd> <kbd>A</kbd> <kbd>S</kbd> <kbd>D</kbd> <kbd>Space</kbd> <kbd>Shift</kbd> to move. Mouse to look.</p>
and they just didn't work. It looked like Vue was reusing the same <p> tag in the markup to render both. Adding a key to each made the transition work (thanks #Mark). The fix should look something like below
<p key="asd" v-if="!isControlling">Take control of the camera by clicking</p>
<p key="asf" v-else>Press <kbd>Esc</kbd> to exit camera. <kbd>W</kbd> <kbd>A</kbd> <kbd>S</kbd> <kbd>D</kbd> <kbd>Space</kbd> <kbd>Shift</kbd> to move. Mouse to look.</p>