元素每次在屏幕上更改位置时如何自动为其设置动画?

时间:2020-10-20 21:18:51

标签: css vue.js animation css-animations css-transitions

我有vue项目。

每次由于 v-if 而页面上的某些元素消失时,页面的其余部分都会稍作重新排列。我希望它能顺利进行。

所有元素都具有:key 属性。

示例: 我已将2个框居中对齐。当一个消失时,第二个仍然居中,因此更改位置。 image

如何处理?

编辑1 我尝试过:

    <div>
        <CompoentA :key=345 class="one-line" v-show="showComponentA" />
        <transition name="moving">
            <CompoentB class="one-line" :key=123 />
        </transition>
    </div>
.one-line { display: inline-table; }
.moving-move { transition: transform 1s; }

2 个答案:

答案 0 :(得分:0)

v-if将从DOM中删除该元素,因此您无法为消失的组件设置动画。

如果要为其设置动画,则应改用v-show(它们将隐藏在DOM中)。

答案 1 :(得分:0)

我认为您需要“ from”和“ to”值来创建此动画。当从DOM中删除元素时,其他元素将基于“内联”位置放置,因此没有用于创建过渡的值引用。 这里有一个类似的问题,其中height:0和height:auto

的过渡

How can I transition height: 0; to height: auto; using CSS?

我制作了一个样本来解决这个问题,使用宽度(大于内容)和宽度0(不透明度0)隐藏内部内容。要运行此示例,只需单击项目即可将其“删除”(不透明度0和宽度:0),并且由于设置了初始宽度(80px),过渡效果良好。

new Vue({
    el: "#app",
  data: () => ({
    // yes, there is better ways, but let make this sample "simple"
    letters: ['a', 'b', 'c', 'd'],
    visible: {
        a: true,
        b: true,
        c: true,
        d: true,
    }
  })
})
#app {
  /* decoration, you can remove */
  width: 100%; 
  text-align: center;
  background-color: #f4f4f4;
}

.moving {
  /* margin and padding 0 
     because the width content will be set to 0
     if this element has a margin, when removed the margin still display the "space"
  */
  padding: 0; 
  margin: 0;
  font-size: 0; /* remove white space in DOM element */
  display: inline-block;
  opacity: 1;
  transition: width linear .2s;
  
  /* decoration, you can remove */
  width: 80px; 
  border: 1px dotted #ccc;
  cursor: pointer;
}

.moving-content {
  font-size: 18px; /* restore font size */
  display: inline-block;
  
  /* decoration, you can remove */
  background-color: #2af; 
  color: white;
  padding: 20px;
  box-sizing: border-box;
}

.moving.hidden {
  width: 0px;
  opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
    <div v-for="letter in letters"
        :key="letter"
        :class="{ moving: true, hidden: !visible[letter] }" @click="visible[letter] = false">
        <span class="moving-content">
          {{ letter }}
        </span>
    </div>
</div>

参考:

https://stackoverflow.com/a/40785144/1724128

https://stackoverflow.com/a/53127208/1724128