Vue 转换模式在与 v-for 和 v-if 结合使用时不起作用

Vue transition mode don't work when combined with v-for and v-if

在带有 Vuetify 的 Vue 中,我想用 animate.css 动态更改 v-cards,但我遇到了问题。 out-in 模式不想在这种情况下工作。淡入和淡出动画同时移动。如何强制它在结束淡入后开始淡入动画?

new Vue({
  el: '#app',
  data() {
    return {
      number: 1,
      items: [
        {
          text: "a",
          number: 1
        },
        {
          text: "b",
          number: 2
        },
        {
          text: "c",
          number: 3
        },
      ]
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script><script src="https://unpkg.com/vuetify/dist/vuetify.min.js"></script>
<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/animate.css" rel="stylesheet"/>

<div id="app">
  <div v-for="(item, index) in items" :key="index">
    <transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
      <v-card dark class="ma-3" v-if="number === item.number">
        <p>{{item.text}}</p>
      </v-card>
    </transition>
  </div>
  <br>
  <v-btn @click="number++; if(number === 4) number = 1;">Next</v-btn>
</div>

https://codepen.io/km2442/pen/zgmmwz

怎么了?

你的过渡是在一个循环内,这意味着在渲染之后你将有多个 transitions 彼此没有关系(mode 不起作用)......这就是你的方式渲染后模板看起来像:

<div key="0">
    <transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
      <v-card dark class="ma-3" v-if="true">
        <p>a</p>
      </v-card>
    </transition>
 </div>
 <div key="1">
    <transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
     <!-- <v-card dark class="ma-3" v-if="false">
        <p>b</p>
      </v-card> -->
    </transition>
 </div>
 <div key="2">
    <transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
      <!-- <v-card dark class="ma-3" v-if="false">
        <p>c</p>
      </v-card> --> 
    </transition>
 </div>
 <div key="3">
    <transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
      <!-- <v-card dark class="ma-3" v-if="false">
        <p>d</p>
      </v-card> -->
    </transition>
 </div>

因此,当您按下一个按钮时,您是从一个过渡跳到另一个...在这种情况下,mode 丢失了。

我该如何解决这个问题?

我们只需要将整个项目包装在一个过渡中,因此在这种情况下,只有一个 transition 可以检测元素何时退出和新元素何时进入(mode 会起作用):

Vue.config.devtools = false;
Vue.config.productionTip = false;

new Vue({
  el: '#app',
  data() {
    return {
      number: 1,
      items: [{
          text: "a",
          number: 1
        },
        {
          text: "b",
          number: 2
        },
        {
          text: "c",
          number: 3
        },
      ]
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuetify/dist/vuetify.min.js"></script>
<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/animate.css" rel="stylesheet" />

<div id="app">
  <transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
    <template v-for="(item, index) in items">
      <v-card dark class="ma-3" v-if="number === item.number" :key="index">
        <p>{{item.text}}</p>
      </v-card>
  </template>
  </transition>
  <br>
  <v-btn @click="number++; if(number === 4) number = 1;">Next</v-btn>
</div>

在使用 v-for 循环进行迭代时,您应该使用 <transition-group>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"> 
</script><script src="https://unpkg.com/vuetify/dist/vuetify.min.js"></script>
<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/animate.css" rel="stylesheet"/>

<div id="app">
 <transition-group mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
  <div v-for="(item, index) in items" :key="index">
    <v-card dark class="ma-3" v-if="number === item.number">
    <p>{{item.text}}</p>
  </v-card>
 </transition-group>
</div>
<br>
<v-btn @click="number++; if(number === 4) number = 1;">Next</v-btn>
</div>

文档:https://vuejs.org/v2/guide/transitions.html#List-Transitions