Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Vue.js 2.0 transition state


May 07, 2021 Vue.js 2.0


Table of contents


Transition state

Vue's transition system provides a very simple way to set the dynamics of entry, departure, and list. What about the dynamics of the data element itself, such as:

  • Numbers and operations
  • The display of colors
  • The location of the SVG node
  • The size of the element and other properties

All the original numbers are stored in advance and can be converted directly to the numbers. By doing this, we can combine Vue's responsive and component systems with third-party libraries to achieve the transition state of switching elements.

State animation with watcher

Watcher allows us to listen for numeric updates to any numeric property. It might sound abstract, so let's take a look at an example using Tweenjs:

<script src="https://unpkg.com/[email protected]" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" ></script>
<div id="animated-number-demo">
  <input v-model.number="number" type="number" step="20">
  <p>{{ animatedNumber }}</p>
</div>
new Vue({
  el: '#animated-number-demo',
  data: {
    number: 0,
    animatedNumber: 0
  },
  watch: {
    number: function(newValue, oldValue) {
      var vm = this
      function animate (time) {
        requestAnimationFrame(animate)
        TWEEN.update(time)
      }
      new TWEEN.Tween({ tweeningNumber: oldValue })
        .easing(TWEEN.Easing.Quadratic.Out)
        .to({ tweeningNumber: newValue }, 500)
        .onUpdate(function () {
          vm.animatedNumber = this.tweeningNumber.toFixed(0)
        })
        .start()
      animate()
    }
  }
})

0

When you update the values, the animation is triggered. This is a good demonstration, but for values that cannot be stored directly as numbers, such as the values of color in CSS, let's implement an example with Color.js:

<script src="https://unpkg.com/[email protected]" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" ></script>
<script src="https://unpkg.com/[email protected]/color.js" rel="external nofollow" ></script>
<div id="example-7">
  <input
    v-model="colorQuery"
    v-on:keyup.enter="updateColor"
    placeholder="Enter a color"
  >
  <button v-on:click="updateColor">Update</button>
  <p>Preview:</p>
  <span
    v-bind:style="{ backgroundColor: tweenedCSSColor }"
    class="example-7-color-preview"
  ></span>
  <p>{{ tweenedCSSColor }}</p>
</div>
var Color = net.brehaut.Color
new Vue({
  el: '#example-7',
  data: {
    colorQuery: '',
    color: {
      red: 0,
      green: 0,
      blue: 0,
      alpha: 1
    },
    tweenedColor: {}
  },
  created: function () {
    this.tweenedColor = Object.assign({}, this.color)
  },
  watch: {
    color: function () {
      function animate (time) {
        requestAnimationFrame(animate)
        TWEEN.update(time)
      }
      new TWEEN.Tween(this.tweenedColor)
        .to(this.color, 750)
        .start()
      animate()
    }
  },
  computed: {
    tweenedCSSColor: function () {
      return new Color({
        red: this.tweenedColor.red,
        green: this.tweenedColor.green,
        blue: this.tweenedColor.blue,
        alpha: this.tweenedColor.alpha
      }).toCSS()
    }
  },
  methods: {
    updateColor: function () {
      this.color = new Color(this.colorQuery).toRGB()
      this.colorQuery = ''
    }
  }
})
.example-7-color-preview {
  display: inline-block;
  width: 50px;
  height: 50px;
}

Preview:

#000000

Dynamic state transition

Like Vue's staging components, state transitions behind data are updated in real time, which is useful for prototyping. When you modify some variables, even a simple SVG polygon can achieve many unimaginable effects.

Sides: 468 Minimum Radius: 50% Update Interval: 500 milliseconds

Check out the fiddle for the full code shown above.

Organize the transition through components

Managing too many state transitions quickly approaches the complexity of a Vue instance or component, and fortunately many animations can be extracted into dedicated sub-components. Let's rewrite the previous example:

<script src="https://unpkg.com/[email protected]" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" ></script>
<div id="example-8">
  <input v-model.number="firstNumber" type="number" step="20"> +
  <input v-model.number="secondNumber" type="number" step="20"> =
  {{ result }}
  <p>
    <animated-integer v-bind:value="firstNumber"></animated-integer> +
    <animated-integer v-bind:value="secondNumber"></animated-integer> =
    <animated-integer v-bind:value="result"></animated-integer>
  </p>
</div>
// 这种复杂的补间动画逻辑可以被复用
// 任何整数都可以执行动画
// 组件化使我们的界面十分清晰
// 可以支持更多更复杂的动态过渡
// strategies.
Vue.component('animated-integer', {
  template: '<span>{{ tweeningValue }}</span>',
  props: {
    value: {
      type: Number,
      required: true
    }
  },
  data: function () {
    return {
      tweeningValue: 0
    }
  },
  watch: {
    value: function (newValue, oldValue) {
      this.tween(oldValue, newValue)
    }
  },
  mounted: function () {
    this.tween(0, this.value)
  },
  methods: {
    tween: function (startValue, endValue) {
      var vm = this
      function animate (time) {
        requestAnimationFrame(animate)
        TWEEN.update(time)
      }
      new TWEEN.Tween({ tweeningValue: startValue })
        .to({ tweeningValue: endValue }, 500)
        .onUpdate(function () {
          vm.tweeningValue = this.tweeningValue.toFixed(0)
        })
        .start()
      animate()
    }
  }
})
// All complexity has now been removed from the main Vue instance!
new Vue({
  el: '#example-8',
  data: {
    firstNumber: 20,
    secondNumber: 40
  },
  computed: {
    result: function () {
      return this.firstNumber + this.secondNumber
    }
  }
})
+ = 60

20 + 40 = 60

We can use this section in a combination of components to talk about various transition strategies and Vue's built-in transition systems. In short, there are few obstacles to the completion of transition dynamics.