我希望使用VueJs动画数字变化。例如,我有:
{{ number }}
然后number从0变为100,我希望元素计数到100,而不是直接跳到它。我如何在不使用任何第三方(纯Js/VueJs)(不包括VueJs)的情况下做到这一点?
number
0
100
edqdpe6u1#
得到了这个工作作为一个自定义组件:https://jsfiddle.net/5nobcLq0/5/联系我们
<body> <input v-model="number"> <animated-number :number="number"></animated-number> </body>
js
Vue.component('animated-number', { template:"{{ displayNumber }}", props: {'number': { default:0 }}, data () { return { displayNumber:0, interval:false } }, ready () { this.displayNumber = this.number ? this.number : 0; }, watch: { number () { clearInterval(this.interval); if(this.number == this.displayNumber) { return; } this.interval = window.setInterval(() => { if(this.displayNumber != this.number) { var change = (this.number - this.displayNumber) / 10; change = change >= 0 ? Math.ceil(change) : Math.floor(change); this.displayNumber = this.displayNumber + change; } }, 20); } } }) new Vue({ el:'body', });
c9qzyr3d2#
我意识到这是一个较旧的帖子,但我正在寻找类似的东西,我发现了一个直接来自vue.js 2.0文档的示例。你可以在这里找到它:https://v2.vuejs.org/v2/guide/transitioning-state.html#Organizing-Transitions-into-Components我在下面的片段中重新创建了它。
// This complex tweening logic can now be reused between // any integers we may wish to animate in our application. // Components also offer a clean interface for configuring // more dynamic transitions and complex transition // 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() { if (TWEEN.update()) { requestAnimationFrame(animate) } } 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 } } })
<script src="https://cdn.jsdelivr.net/npm/vue@2.4.3/dist/vue.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/tween.js"></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>
我希望这有帮助!蒂姆
rks48beu3#
我采用了Jeff的答案,并使用GSAP对其进行了简化。
import gsap from 'gsap'; Vue.component('animate-integer', { template: '<span>{{displayValue}}</span>', props: { value: { default: 0 } }, data() { return { displayValue: this.value, tweenValue: this.value }; }, watch: { value() { gsap.to(this, { tweenValue: this.value, onUpdate: () => { this.displayValue = Math.ceil(this.tweenValue); } }); } } });
用途:
<input v-model="value"> <animate-integer :value="value"></animated-integer>
当我使用这个组件时,它已经发展到接受持续时间和格式,here is a gist。
7cwmlq894#
如果你想支持浮点数和负数的动画,这个vue组件也可以工作。它建立在@jeff的答案之上。更改数字5或使其成为一个 prop ,以控制动画发生的快慢。
<template> <span>{{displayNumber}}</span> </template> <script> export default { data () { return { displayNumber: 0, counter: false }; }, props: { number: { type: Number, default: 0 } }, watch: { number () { clearInterval(this.counter); if (this.number === this.displayNumber) { return; } this.counter = setInterval(function () { if (Math.floor(this.displayNumber) !== Math.floor(this.number)) { var change = (this.number - this.displayNumber) / 5; change = change >= 0 ? Math.ceil(change) : Math.floor(change); this.displayNumber = this.displayNumber + change; } else { this.displayNumber = this.number; clearInterval(this.counter); } }.bind(this), 20); } } }; </script>
cnwbcb6i5#
如果你想要一个vue 3组合API组件,基于@jeff和@AnandShiva的答案。这就是:
<template>{{ displayNumber }}</template> <script setup> const props = defineProps({ value: { type: Number, default: 0, }, speed: { // smaller is faster type: Number, default: 5, }, }); const displayNumber = ref(props.value); let interval = null; watch( () => props.value, (newVal) => { clearInterval(interval); if (newVal === displayNumber.value) { return; } interval = setInterval(() => { if (Math.floor(displayNumber.value) !== Math.floor(newVal)) { var change = (newVal - displayNumber.value) / props.speed; change = change >= 0 ? Math.ceil(change) : Math.floor(change); displayNumber.value = displayNumber.value + change; } else { displayNumber.value = newVal; clearInterval(interval); } }, 20); } ); </script>
5条答案
按热度按时间edqdpe6u1#
得到了这个工作作为一个自定义组件:https://jsfiddle.net/5nobcLq0/5/
联系我们
js
c9qzyr3d2#
我意识到这是一个较旧的帖子,但我正在寻找类似的东西,我发现了一个直接来自vue.js 2.0文档的示例。你可以在这里找到它:https://v2.vuejs.org/v2/guide/transitioning-state.html#Organizing-Transitions-into-Components
我在下面的片段中重新创建了它。
我希望这有帮助!蒂姆
rks48beu3#
如果使用GSAP
我采用了Jeff的答案,并使用GSAP对其进行了简化。
用途:
更新
当我使用这个组件时,它已经发展到接受持续时间和格式,here is a gist。
7cwmlq894#
如果你想支持浮点数和负数的动画,这个vue组件也可以工作。它建立在@jeff的答案之上。更改数字5或使其成为一个 prop ,以控制动画发生的快慢。
cnwbcb6i5#
如果你想要一个vue 3组合API组件,基于@jeff和@AnandShiva的答案。这就是: