Eino Gourdin
Eino Gourdin

Reputation: 4507

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>

Upvotes: 0

Views: 317

Answers (2)

xiao
xiao

Reputation: 1

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.

Upvotes: 0

Michal Lev&#253;
Michal Lev&#253;

Reputation: 37803

It works just fine in plain JS...

So try to focus on the differences:

  1. TypeScript (i cannot use it here on SO) - I really doubt its the cause but you can try
  2. 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>

Upvotes: 1

Related Questions