Vue.js过渡 – 根据增加/减少的值进行进入和离开的效果

huangapple go评论70阅读模式
英文:

Vue.js Transitions - enter and leave, dependent on increment/decrementing value

问题

我目前有以下的过渡块组件:

<div
   v-if="!surveyResultIsReady"
   class="vh-md-40 position-relative"
   >
   <transition
      name="custom-classes-transition"
      enter-active-class="animated slideInRight"
      leave-active-class="animated slideOutLeft"
      >
      <div
         v-bind:key="step"
         class="w-100 position-absolute mx-auto"
         >
         <SurveyActiveQuestion
            v-if="!surveyResultIsReady"
            v-bind:question="activeQuestion()"
            v-bind:totalQuestions="totalQuestions"
            v-on:activeQuestionAnswered="activeQuestionAnswered()"
            />
      </div>
   </transition>
</div>

过渡由 this.step 值(v-bind:key="step")控制。

this.step++ 时,过渡效果看起来很好,向正确的方向滑动:从左到右滑动。但是,当 this.step-- 时,过渡效果相同。

我想知道,如何将它修正为在 this.step-- 方向上从右向左滑动?

英文:

I currently have the following transition block component:

<div
   v-if="!surveyResultIsReady"
   class="vh-md-40 position-relative"
   >
   <transition
      name="custom-classes-transition"
      enter-active-class="animated slideInRight"
      leave-active-class="animated slideOutLeft"
      >
      <div
         v-bind:key="step"
         class="w-100 position-absolute mx-auto"
         >
         <SurveyActiveQuestion
            v-if="!surveyResultIsReady"
            v-bind:question="activeQuestion()"
            v-bind:totalQuestions="totalQuestions"
            v-on:activeQuestionAnswered="activeQuestionAnswered()"
            />
      </div>
   </transition>
</div>

The transition is governed by the this.step value (v-bind:key="step").

The transition looks great when this.step++, the transition swipes in the "correct" direction: swiping in left to right. However, when this.step-- the transition is the same.

I was wondering, how would I correct this to swipe back right to left for the this.step-- direction?

答案1

得分: 1

你需要为过渡效果创建两个不同的CSS进入状态,因为你想要从两个方向滑入。通过使用enter-class(与enter-active-class不同),你可以将滑动位置隔离到两个单独的CSS进入类中,并根据step的变化来交换它们。例如,这是新的绑定:

:enter-class="enterClass"

enterClass是一个数据属性,根据step的变化,它被设置为增加或减少的类名字符串,使用watch来监视step

watch: {
  step(old, value) {
    this.enterClass = value > old ? 'slide-in-right' : 'slide-in-left'; 
  }
}

以下是这些类的CSS样式:

.animated {
  transition: transform .5s;
}
.slide-in-left {
  transform: translate(-100%, 0);
}
.slide-in-right {
  transform: translate(100%, 0);
}

演示
将所有内容放在一起,这是你代码的简化版本:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->
new Vue({
  el: "#app",
  data() {
    return {
      step: 1,
      enterClass: ''
    }
  },
  watch: {
    step(value, old) {
      this.enterClass = value > old ? 'slide-in-left' : 'slide-in-right'; 
    }
  }
});
<!-- language: lang-css -->
[v-cloak] {
  display:none;
}

#app {
  background: #fff;
  border-radius: 4px;
}

.slider {
  position: relative;
  overflow-x: hidden;
  border: 1px solid #cccccc;
  border-radius: 3px;
  height: 40px;
  margin-bottom: 4px;
}

.slider > div {
  position: absolute;
  width: 100%;
  text-align: center;
}

.animated {
  transition: transform .5s;
}
.slide-in-left {
  transform: translate(-100%, 0);
}
.slide-in-right {
  transform: translate(100%, 0);
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" v-cloak>
  <div class="slider">
    <transition name="slide"
      enter-active-class="animated"
      :enter-class="enterClass"
    >
      <div :key="step">
        Content <br />
        {{ step }}
      </div>
    </transition>
  </div>
  <button @click="--step">-</button>
  <button @click="++step">+</button>
</div>

<!-- end snippet -->

如果你想要更复杂的效果,可以以相同的方式添加leave-class

英文:

You need two different CSS enter states for the transition because you want to slide in from both directions. Using a binding for enter-class (not the same as enter-active-class), you can isolate the slide positioning into 2 separate CSS enter classes and swap them based on the change in step. For example, here is the new binding:

:enter-class=&quot;enterClass&quot;

enterClass is a data property set to either the incrementing or decrementing class name string using a watch on step:

watch: {
  step(old, value) {
	this.enterClass = value &gt; old ? &#39;slide-in-right&#39; : &#39;slide-in-left&#39;; 
  }
}

And here are the classes:

.animated {
  transition: transform .5s;
}
.slide-in-left {
  transform: translate(-100%, 0);
}
.slide-in-right {
  transform: translate(100%, 0);
}

DEMO
Putting it all together, here is a simplified version of your code:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

new Vue({
  el: &quot;#app&quot;,
  data() {
    return {
      step: 1,
      enterClass: &#39;&#39;
    }
  },
  watch: {
    step(value, old) {
      this.enterClass = value &gt; old ? &#39;slide-in-left&#39; : &#39;slide-in-right&#39;; 
    }
  }
});

<!-- language: lang-css -->

[v-cloak] {
  display:none;
}

#app {
  background: #fff;
  border-radius: 4px;
}

.slider {
  position: relative;
  overflow-x: hidden;
  border: 1px solid #cccccc;
  border-radius: 3px;
  height: 40px;
  margin-bottom: 4px;
}

.slider &gt; div {
  position: absolute;
  width: 100%;
  text-align: center;
}

.animated {
  transition: transform .5s;
}
.slide-in-left {
  transform: translate(-100%, 0);
}
.slide-in-right {
  transform: translate(100%, 0);
}

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js&quot;&gt;&lt;/script&gt;
&lt;div id=&quot;app&quot; v-cloak&gt;
  &lt;div class=&quot;slider&quot;&gt;
    &lt;transition name=&quot;slide&quot;
      enter-active-class=&quot;animated&quot;
      :enter-class=&quot;enterClass&quot;
    &gt;
      &lt;div :key=&quot;step&quot;&gt;
        Content &lt;br /&gt;
        {{ step }}
      &lt;/div&gt;
    &lt;/transition&gt;
  &lt;/div&gt;
  &lt;button @click=&quot;--step&quot;&gt;-&lt;/button&gt;
  &lt;button @click=&quot;++step&quot;&gt;+&lt;/button&gt;
&lt;/div&gt;

<!-- end snippet -->

You can add leave-class in the same way if you want to make it fancier

答案2

得分: 0

你可以使用GSAP。我在视频中看到了它(链接和时间戳)https://youtu.be/14yOawLavB0?t=734
那里有示例代码(你可以轻松地按照你的步骤使用它)和结果。

英文:

You can use GSAP. I saw it in the video (link with timing) https://youtu.be/14yOawLavB0?t=734
there is example of code (you can ease use it with your steps) and result.

huangapple
  • 本文由 发表于 2020年1月6日 19:05:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/59610962.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定