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

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

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

问题

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

  1. <div
  2. v-if="!surveyResultIsReady"
  3. class="vh-md-40 position-relative"
  4. >
  5. <transition
  6. name="custom-classes-transition"
  7. enter-active-class="animated slideInRight"
  8. leave-active-class="animated slideOutLeft"
  9. >
  10. <div
  11. v-bind:key="step"
  12. class="w-100 position-absolute mx-auto"
  13. >
  14. <SurveyActiveQuestion
  15. v-if="!surveyResultIsReady"
  16. v-bind:question="activeQuestion()"
  17. v-bind:totalQuestions="totalQuestions"
  18. v-on:activeQuestionAnswered="activeQuestionAnswered()"
  19. />
  20. </div>
  21. </transition>
  22. </div>

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

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

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

英文:

I currently have the following transition block component:

  1. <div
  2. v-if="!surveyResultIsReady"
  3. class="vh-md-40 position-relative"
  4. >
  5. <transition
  6. name="custom-classes-transition"
  7. enter-active-class="animated slideInRight"
  8. leave-active-class="animated slideOutLeft"
  9. >
  10. <div
  11. v-bind:key="step"
  12. class="w-100 position-absolute mx-auto"
  13. >
  14. <SurveyActiveQuestion
  15. v-if="!surveyResultIsReady"
  16. v-bind:question="activeQuestion()"
  17. v-bind:totalQuestions="totalQuestions"
  18. v-on:activeQuestionAnswered="activeQuestionAnswered()"
  19. />
  20. </div>
  21. </transition>
  22. </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的变化来交换它们。例如,这是新的绑定:

  1. :enter-class="enterClass"

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

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

以下是这些类的CSS样式:

  1. .animated {
  2. transition: transform .5s;
  3. }
  4. .slide-in-left {
  5. transform: translate(-100%, 0);
  6. }
  7. .slide-in-right {
  8. transform: translate(100%, 0);
  9. }

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

  1. <!-- begin snippet: js hide: false console: true babel: false -->
  2. <!-- language: lang-js -->
  3. new Vue({
  4. el: "#app",
  5. data() {
  6. return {
  7. step: 1,
  8. enterClass: ''
  9. }
  10. },
  11. watch: {
  12. step(value, old) {
  13. this.enterClass = value > old ? 'slide-in-left' : 'slide-in-right';
  14. }
  15. }
  16. });
  17. <!-- language: lang-css -->
  18. [v-cloak] {
  19. display:none;
  20. }
  21. #app {
  22. background: #fff;
  23. border-radius: 4px;
  24. }
  25. .slider {
  26. position: relative;
  27. overflow-x: hidden;
  28. border: 1px solid #cccccc;
  29. border-radius: 3px;
  30. height: 40px;
  31. margin-bottom: 4px;
  32. }
  33. .slider > div {
  34. position: absolute;
  35. width: 100%;
  36. text-align: center;
  37. }
  38. .animated {
  39. transition: transform .5s;
  40. }
  41. .slide-in-left {
  42. transform: translate(-100%, 0);
  43. }
  44. .slide-in-right {
  45. transform: translate(100%, 0);
  46. }
  47. <!-- language: lang-html -->
  48. <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
  49. <div id="app" v-cloak>
  50. <div class="slider">
  51. <transition name="slide"
  52. enter-active-class="animated"
  53. :enter-class="enterClass"
  54. >
  55. <div :key="step">
  56. Content <br />
  57. {{ step }}
  58. </div>
  59. </transition>
  60. </div>
  61. <button @click="--step">-</button>
  62. <button @click="++step">+</button>
  63. </div>
  64. <!-- 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:

  1. :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:

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

And here are the classes:

  1. .animated {
  2. transition: transform .5s;
  3. }
  4. .slide-in-left {
  5. transform: translate(-100%, 0);
  6. }
  7. .slide-in-right {
  8. transform: translate(100%, 0);
  9. }

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 -->

  1. new Vue({
  2. el: &quot;#app&quot;,
  3. data() {
  4. return {
  5. step: 1,
  6. enterClass: &#39;&#39;
  7. }
  8. },
  9. watch: {
  10. step(value, old) {
  11. this.enterClass = value &gt; old ? &#39;slide-in-left&#39; : &#39;slide-in-right&#39;;
  12. }
  13. }
  14. });

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

  1. [v-cloak] {
  2. display:none;
  3. }
  4. #app {
  5. background: #fff;
  6. border-radius: 4px;
  7. }
  8. .slider {
  9. position: relative;
  10. overflow-x: hidden;
  11. border: 1px solid #cccccc;
  12. border-radius: 3px;
  13. height: 40px;
  14. margin-bottom: 4px;
  15. }
  16. .slider &gt; div {
  17. position: absolute;
  18. width: 100%;
  19. text-align: center;
  20. }
  21. .animated {
  22. transition: transform .5s;
  23. }
  24. .slide-in-left {
  25. transform: translate(-100%, 0);
  26. }
  27. .slide-in-right {
  28. transform: translate(100%, 0);
  29. }

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

  1. &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js&quot;&gt;&lt;/script&gt;
  2. &lt;div id=&quot;app&quot; v-cloak&gt;
  3. &lt;div class=&quot;slider&quot;&gt;
  4. &lt;transition name=&quot;slide&quot;
  5. enter-active-class=&quot;animated&quot;
  6. :enter-class=&quot;enterClass&quot;
  7. &gt;
  8. &lt;div :key=&quot;step&quot;&gt;
  9. Content &lt;br /&gt;
  10. {{ step }}
  11. &lt;/div&gt;
  12. &lt;/transition&gt;
  13. &lt;/div&gt;
  14. &lt;button @click=&quot;--step&quot;&gt;-&lt;/button&gt;
  15. &lt;button @click=&quot;++step&quot;&gt;+&lt;/button&gt;
  16. &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:

确定