【问题标题】:Transition multiple elements at the same time on Vue component render在 Vue 组件渲染上同时转换多个元素
【发布时间】:2021-03-03 10:00:58
【问题描述】:

如下jsfiddle所示的简单案例:

https://jsfiddle.net/hsak2rdu/

我想交换两个元素并为其设置动画,但失败了。在 Playground 中单击切换按钮后可以看到,第二个元素闪烁到最终位置。

我希望它们同时具有动画效果,就像相互交叉一样。有可能吗?

模板:

<div id="app">
  <div class="dom" v-for="(_d, _i) in list" :key="_d.id" :style="{ top: _i * 50 + 'px'}">
    <span>{{_d.text}}{{_i}}</span>
  </div>
  <button @click="handle">Toggle</button>
  {{list}}
</div>

JS:

new Vue({
  el: '#app',
  data: {
    show: true,
    list: [
      {
        id:1,
        text:'First'
      },
      {
        id:2,
        text:'Second'
      }
    ]
  },
  methods:{
    handle: function (){
      console.log("DEBUG", this.list)
      let a = JSON.parse(JSON.stringify(this.list[0]));
      let b = JSON.parse(JSON.stringify(this.list[1]))
      this.$set(this.list, 0, b);
      this.$set(this.list, 1, a);
    }
  }
});

【问题讨论】:

    标签: javascript html css vue.js vue-transitions


    【解决方案1】:

    唯一必要的更改是将v-for 包装在&lt;transition-group&gt; 中:

    <transition-group tag="div" name="list">
      <div class="dom" v-for="(_d, _i) in list" :key="_d.id" :style="{ top: _i * 20 + 'px' }">
        <span>{{_d.text}}{{_i}}</span>
      </div>
    </transition-group>
    

    来自docs

    这似乎很神奇,但在底层,Vue 使用了一种名为 FLIP 的动画技术,通过变换将元素从旧位置平滑过渡到新位置

    这是一个演示:

    new Vue({
      el: '#app',
      data: () => ({
        show: true,
        list: [
          {
            id:1,
            text:'First'
          },
          {
            id:2,
            text:'Second'
          }
        ]
      }),
      methods:{
        handle: function (){
          console.log("DEBUG", this.list)
          let a = JSON.parse(JSON.stringify(this.list[0]));
          let b = JSON.parse(JSON.stringify(this.list[1]))
          this.$set(this.list, 0, b);
          this.$set(this.list, 1, a);
        }
      }
    });
    .dom{
      position: absolute;
      transition: all 1s linear;
      opacity: 1;
    }
    button{
      margin-top: 50px;
    }
    #app{
      margin-top: 50px;
      position: relative;
    }
    <div id="app">
      <transition-group tag="div" name="list">
        <div class="dom" v-for="(_d, _i) in list" :key="_d.id" :style="{ top: _i * 20 + 'px' }">
          <span>{{_d.text}}{{_i}}</span>
        </div>
      </transition-group>
      <button @click="handle">Toggle</button>
      {{list}}
    </div>
    
    <script src="https://unpkg.com/vue/dist/vue.js"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 2019-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-10
      相关资源
      最近更新 更多