Vue过渡不起作用

时间:2018-04-21 00:45:29

标签: vue.js vuejs2

我想知道我在这里做错了我的过渡不起作用。我试图让开关在点击时向右或向左移动,它正在工作但没有过渡。我想我在这里失踪了。

<template>
<div class="switchery" @click="activate" >
      <div class="switchery-check" v-bind:class="{active:isactive}"></div>
</div>
</template>

    <script>
      export default {
        data:function(){
          return{
            isactive:false
          }
        },
        methods:{
          activate:function (event) {
                 this.checked  = !this.checked;
                 this.isactive = this.checked;
          }
        }
      };

    </script>

    <style scoped>

    .switchery{
      width: 40px;
      height: 20px;
      border-radius: 20px;
      background-color: #09c;
      cursor: pointer;
      position: relative;
    }

    .switchery-check{
      transition: all 5s !important;
      position: absolute;
      left: 0;
      top: 0;
      height: 100%;
      width: 20px;
      background-color: #fff;
      border-radius: 100%;
    }

    .active.switchery-check {
      right: 0 !important;
      left: auto !important;
    }
    </style>

2 个答案:

答案 0 :(得分:2)

事情是rightleft没有触发动画,但您的过渡配置得很好,看看background: red;如何完美转换:

&#13;
&#13;
new Vue({
  el: '#app',
  data: function() {
    return {
      isactive: false
    }
  },
  methods: {
    activate: function(event) {
      this.checked = !this.checked;
      this.isactive = this.checked;
    }
  }
})
&#13;
.switchery {
  width: 40px;
  height: 20px;
  border-radius: 20px;
  background-color: #09c;
  cursor: pointer;
  position: relative;
}

.switchery-check {
  transition: all 5s !important;
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 20px;
  background-color: #fff;
  border-radius: 100%;
}

.active.switchery-check {
  background: red; /* added for demo */
  right: 0 !important;
  left: auto !important;
}
&#13;
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <div class="switchery" @click="activate">
    <div class="switchery-check" v-bind:class="{active:isactive}"></div>
  </div>
</div>
&#13;
&#13;
&#13;

对于您的情况,一个替代方案是transform: translate(100%);而不是rightleft

&#13;
&#13;
new Vue({
  el: '#app',
  data: function() {
    return {
      isactive: false
    }
  },
  methods: {
    activate: function(event) {
      this.checked = !this.checked;
      this.isactive = this.checked;
    }
  }
})
&#13;
.switchery {
  width: 40px;
  height: 20px;
  border-radius: 20px;
  background-color: #09c;
  cursor: pointer;
  position: relative;
}

.switchery-check {
  transition: all 5s !important;
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 20px;
  background-color: #fff;
  border-radius: 100%;
}

.active.switchery-check {
  background: red; /* added for demo */
  transform: translate(100%);
}
&#13;
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <div class="switchery" @click="activate">
    <div class="switchery-check" v-bind:class="{active:isactive}"></div>
  </div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

补充@ acdcjunior的回答,我想澄清一下你的演示实际发生了什么:

你实际上接近一个有效的解决方案(虽然不一定是最佳的)。问题与您在转换类left: auto)中使用.active.switchery-check有关,在本例中specifies 元素的位置基于{{1}属性。由于right在基类(right)中没有初始值,因此不会发生转换,并且元素会立即移动到右边缘。

一种解决方案是在转换类中将.switchery-check更改为left: auto,其中left: 20px是容器元素的宽度,在基类中指定:

20px

.switchery-check {
  left: 0;
}
.active.switchery-check {
  left: 20px;
}
new Vue({
  el: '#app',
  data: function() {
    return {
      isactive: false
    }
  },
  methods: {
    activate: function(event) {
      this.checked = !this.checked;
      this.isactive = this.checked;
    }
  }
})
.switchery {
  width: 40px;
  height: 20px;
  border-radius: 20px;
  background-color: #09c;
  cursor: pointer;
  position: relative;
}

.switchery-check {
  transition: all 200ms !important;
  position: absolute;
  left: 0;              /* property to transition: left */
  top: 0;
  height: 100%;
  width: 20px;
  background-color: #fff;
  border-radius: 100%;
}

.active.switchery-check {
  left: 20px;
}

body {
  display: flex;
  justify-content: center;
  background: #444;
}

由于<script src="https://unpkg.com/vue@2.5.16"></script> <div id="app"> <div class="switchery" @click="activate"> <div class="switchery-check" v-bind:class="{active:isactive}"></div> </div> </div>是根据right计算的,您可以使用上面的相同解决方案,为left交换right

left

.switchery-check {
  right: 20px;
}
.active.switchery-check {
  right: 0;
}
new Vue({
  el: '#app',
  data: function() {
    return {
      isactive: false
    }
  },
  methods: {
    activate: function(event) {
      this.checked = !this.checked;
      this.isactive = this.checked;
    }
  }
})
.switchery {
  width: 40px;
  height: 20px;
  border-radius: 20px;
  background-color: #09c;
  cursor: pointer;
  position: relative;
}

.switchery-check {
  transition: all 200ms !important;
  position: absolute;
  right: 20px;              /* property to transition: right */
  top: 0;
  height: 100%;
  width: 20px;
  background-color: #fff;
  border-radius: 100%;
}

.active.switchery-check {
  right: 0;
}

body {
  display: flex;
  justify-content: center;
  background: #444;
}

除此之外:如果同时定义<script src="https://unpkg.com/vue@2.5.16"></script> <div id="app"> <div class="switchery" @click="activate"> <div class="switchery-check" v-bind:class="{active:isactive}"></div> </div> </div>left,则元素的位置为过度指定MDN

正如@acdcjunior所指出的,动画right / left的替代方法是使用right。这个解决方案有一些优点:

  • 更好的效果浏览器cheaply animate可以transform: translateX(100%)。使用transform: translateX() / left制作动画会导致布局相对昂贵并导致抖动,具体取决于页面上这些元素的数量。您可以在Chrome DevTools Performance面板中验证这一点:开始录制,单击切换开关以开始动画,停止录制,并检查事件日志的活动列。 (在macOS High Sierra的Chrome 66中测试)

  • 更易维护的CSS 容器宽度只需要设置一次,并且只能在基类中设置。也就是说,right.switchery-check,这是唯一需要设置的属性。无需width: 20pxleft匹配此设置。事实上,在使用right时,您根本不需要设置leftright

transform: translateX(100%)
new Vue({
  el: '#app',
  data: function() {
    return {
      isactive: false
    }
  },
  methods: {
    activate: function(event) {
      this.checked = !this.checked;
      this.isactive = this.checked;
    }
  }
})
.switchery {
  width: 40px;
  height: 20px;
  border-radius: 20px;
  background-color: #09c;
  cursor: pointer;
  position: relative;
}

.switchery-check {
  transition: all 200ms !important;
  position: absolute;
  top: 0;
  height: 100%;
  width: 20px;
  background-color: #fff;
  border-radius: 100%;
}

.active.switchery-check {
  transform: translateX(100%); /* NO NEED TO SET left OR right */
}

body {
  display: flex;
  justify-content: center;
  background: #444;
}

  • 更具可读性的CSS 在过渡课程中,使用<script src="https://unpkg.com/vue@2.5.16"></script> <div id="app"> <div class="switchery" @click="activate"> <div class="switchery-check" v-bind:class="{active:isactive}"></div> </div> </div>动画识别的属性一目了然,而不是获取transform: translateX(100%) / left设置在两个不同的类中正确。