如何在 Vue 中重置 CSS 动画 [英] How to reset CSS animations in Vue
问题描述
我有一个这样的列表:
var v = new Vue({'el' : '#app','数据' : {'列表':[1,2,3,4,5,6,7,8,9,10]},方法: {activateClass($event){$event.target.classList.remove('animate');无效 $event.target.offsetWidth;$event.target.classList.add('animate');},改变随机值(){var randomAmount = Math.round(Math.random() * 12);var randomIndex = Math.floor(Math.random() * this.list.length);Vue.set(this.list, randomIndex, randomAmount)}},安装(){var vm = 这个;设置间隔(函数(){vm.changeRandomValue();}, 500);}})
.animate{动画:淡入 0.5 秒;}@关键帧淡出{0% { 背景:蓝色;}100% { 背景:白色;}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script><div id="应用程序"><ul><li v-for="列表中的项目" v-html="item" @click="activateClass($event)"></li>
如果你运行上面的代码片段,你会看到如果你点击一个 li 它将使用这个代码:
activateClass($event){$event.target.classList.remove('animate');无效 $event.target.offsetWidth;$event.target.classList.add('animate');}
向其添加一次类并播放动画(https://css-技巧.com/restart-css-animation/).太棒了!
现在,我还有一个 changeRandomValue()
函数,它从列表数组中选择一个元素并更改其值.
如何在 changeRandomValue
方法内部使用 activateClass
方法?
我有一些关于在元素上使用事件的想法,所以它会是这样的:
但我认为不存在这样的事情.我也一直在研究观察者,但我不认为这真的是他们的目的.
我可以获取被点击的元素并找到它引用的数据,但我不知道如何获取已更改的数据,然后找到它的 dom 引用.
我不使用类绑定的原因是我需要触发回流.也许使用 vue 有一种非常简单的方法可以做到这一点,但我不知道.
一个简单的解决方案是使用 类绑定 和animationend
事件.
您还可以以编程方式触发相同的解决方案,如 mounted
事件所示.
new Vue({el: '#app',数据: {项目: [{编号:1,亮点:假}, {编号:2,亮点:假}]},安装(){//演示程序化突出显示setTimeout(() => {this.items[1].highlight = truesetTimeout(() => {this.items[1].highlight = true}, 1000)}, 1000)},方法: {添加类(项目){item.highlight = true},移除类(项目){item.highlight = false}}})
p {光标:指针;}.animate {动画:淡入 0.5 秒;}@关键帧淡出{0% {背景:蓝色;}100% {背景:白色;}}
<script src="https://unpkg.com/vue"></script><div id="应用程序"><p v-for="item in items" v-bind:class="{ animate: item.highlight }" v-on:click="addClass(item)" v-on:animationend="removeClass(item)">{{ item.id }}</p>
I have a list like this:
var v = new Vue({
'el' : '#app',
'data' : {
'list' : [1,2,3,4,5,6,7,8,9,10]
},
methods: {
activateClass($event){
$event.target.classList.remove('animate');
void $event.target.offsetWidth;
$event.target.classList.add('animate');
},
changeRandomValue(){
var randomAmount = Math.round(Math.random() * 12);
var randomIndex = Math.floor(Math.random() * this.list.length);
Vue.set(this.list, randomIndex, randomAmount)
}
},
mounted(){
var vm = this;
setInterval(function(){
vm.changeRandomValue();
}, 500);
}
})
.animate{
animation: fade 0.5s;
}
@keyframes fade{
0% { background:blue; }
100% { background:white; }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
<ul>
<li v-for="item in list" v-html="item" @click="activateClass($event)"></li>
</ul>
</div>
If you run the above snippet, you'll see that if you click an li it will use this code:
activateClass($event){
$event.target.classList.remove('animate');
void $event.target.offsetWidth;
$event.target.classList.add('animate');
}
To add a class to it once and play an animation (https://css-tricks.com/restart-css-animation/). Awesome!
Now, I also have a changeRandomValue()
function that selects one element from the list array and change its value.
How would I use the activateClass
method from inside of the changeRandomValue
method?
I've had a few thoughts about using events on the element, so it would be something like:
<li v-for="item in list" v-html="item"
@click="activateClass($event)"
@myValueChanged="activateClass($event)"
></li>
But I don't think anything like that exists. I have also been looking into watchers but I don't think this is really what they are for.
I have no problem taking the element that has been clicked and finding the data that it is referencing, but I can't work out how to take the data that has been changed and then find its dom reference.
The reason I'm not using class bindings is that I need to trigger a reflow. Maybe there is a really easy way to do that with vue, but I'm not aware of it.
One easy solution would be to use class bindings and the animationend
event.
You can also trigger the same solution programmatically, as shown in the mounted
event.
new Vue({
el: '#app',
data: {
items: [{
id: 1,
highlight: false
}, {
id: 2,
highlight: false
}]
},
mounted() {
// Demonstrate programmatic highlighting
setTimeout(() => {
this.items[1].highlight = true
setTimeout(() => {
this.items[1].highlight = true
}, 1000)
}, 1000)
},
methods: {
addClass(item) {
item.highlight = true
},
removeClass(item) {
item.highlight = false
}
}
})
p {
cursor: pointer;
}
.animate {
animation: fade 0.5s;
}
@keyframes fade {
0% {
background: blue;
}
100% {
background: white;
}
}
<script src="https://unpkg.com/vue"></script>
<div id="app">
<p v-for="item in items" v-bind:class="{ animate: item.highlight }" v-on:click="addClass(item)" v-on:animationend="removeClass(item)">{{ item.id }}</p>
</div>
这篇关于如何在 Vue 中重置 CSS 动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!