-
-
Notifications
You must be signed in to change notification settings - Fork 33.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
v-for 与 transition 同时应用时频繁更新下元素存在清理不干净的情况 #2452
Comments
我觉得 这应该不是 vue的 一个bug。 而是使用上存在一些「未知」的问题。 比如 : 你的 css leave 的动画 没有添加,导致 「退场」动画没有执行。 所以安装 vue 中的 transitionend or annimationend 没有执行, 进而导致 元素会 出现如你描述的「清理不干净」的情况。 这个问题 我在之前的开发中也遇到过,检查后确定是自己的问题。 建议你先自检一遍,如果还有这样的问题。 建议 可以在 jsfiddle.net 上使用示例代码的方式来更方便的 debug |
实际上退场动画已经执行了,因为部分元素已经退出,还残留了一部分元素没有被清理。 |
stagger并没有解决问题。。。。 |
我机器按你的两个描述都无法重现,请上代码吧。 |
Reproduction Linkhttps://jsfiddle.net/ClassicOldSong/1utjmu60/5/ 操作方法:点击Start filling,然后点击Start removing,观测结果即可 console里有输出beforeLeave和afterLeave的触发次数,可以发现afterLeave的次数小于beforeLeave |
我认为你的demo产生的问题.... 和vue没有关系啊... |
@taoche 但是这里没有任何其他途径操作元素啊。。。所以你觉得问题出在了哪里。。。 |
I think the reason causing your problem is setInterval(). Since javascript is single thread, the stop setInterval() will be queued and cannot be executed until the first one finish. |
@YidingW Actually in production environment I did not use setInterval(), all the actions were triggered by user, definitely no setInterval(). I'm working on a online chat room, where users could recall their message. But I found that when they do this too frequently there will left some elements on page. Here I just use setInterval() to simulate this action. Now I just add a timer on beforeLeave, at the time when the exiting animation should be finished if the element wasn't removed properly, jquery would remove it from document. This is just a temporary solution to this problem. |
你好,这个问题出现在于你的css中,并不是data的问题。 只需要调整css效果时间,或者考虑改变下你应用的机制。我想知道了哪里出的问题,你应该很快能找到解决方案。 |
@EveLuty 实际上Vue的工作机制是这样的:当发现你的数据变动以后才会去进行元素操作比如添加或者移除。而我遇到的问题是Vue已经发现了数据变化,而且知道这个元素需要被清除,已经执行了退场动画,却在最后一步的处理上出了问题。所以我并不是十分认同你的看法。 |
你所谓的最后一步的处理出了问题,并不然,持续产生阴影的原因是你在dome中永不停歇的push。所以for一直在执行。即使你使得data=[], 那么数据也会在你设定好的动画中渐进消失,在动画结束之前并不会立刻清空,而你又持续push,所以导致这样。 而阴影滞留呢,无一例外都是data设为空集合之后新添加数据造成的。是因为是新push的数据还未完全走完过渡效果,就原数据被清空造成的。导致在离开效果进行时,已经丢失了跟原数据的绑定。但是这种应用案例应该并不多吧。 由css过渡效果时间引起的问题。我不确定这只发生于vuejs,或者是针对所有类似情况都会发生。 最后,有两个方法可以解决这个问题,
这种方案在使用后,依然能看到有三到四行残留,是因为你在不停push,正常现象。 就这样了。如果还有问题,就等尤大大回复吧~~ |
@EveLuty 我设置为opacity: 0.1只是为了更直观地展现这个问题。。因为在实际应用中我的处理方式就是opacity: 0。具体应用场景我在回复YidingW的时候已经说明,我无法阻止用户在动画结束之前向里面推送新的消息。而且你可以尝试一下将 data=[] 换成 data.splice(data.length - 1, 1) 之类的操作方式,一样会出现问题(比如https://jsfiddle.net/ClassicOldSong/1utjmu60/7/ ,stop后依旧会有残留,而且让我很纳闷的是,数据绑定如果已经丢失的话为何还能继续响应click事件)。 所以估计只能等待尤大大回复了。。。 |
恩,按opacity:0的方式就都没有问题了。 问题还是在于动画时间导致数据删除并不及时,我又测试了下,如果你在start的里面加入简单的console查看data的长度,会有概率出现等于2的时候,就是说在push之前,数据中并不为空,也验证了我说的,清空在更短周期内执行,并不代表会比push之前完成清空数组的任务,导致出现这种问题。 (另外,如果这两个方法的时间周期如果一致,也不会出现问题,并且动画数量也一致) 至于最后的疑问,数据绑定丢失,但是你的html中该元素的click事件还是指向vue里的方法呀 :) 你可以看看。 |
@EveLuty 我的意思是。。。我在opacity: 0的时候发现了这个问题。。。。我纳闷的是传入参数而不是click事件本身,也就是说Vue内部的引用对象其实也没有被清理干净 补充:刚刚尝试了一下在fill的循环里检测datas长度,无论是直接vm.datas还是vm.$data.datas的长度都没有发现不为0的情况,在我看来以及从数学的角度上来分析是fill之前已经清空了,麻烦指点一下如何正确地追踪。。。 |
首先,你真的按我的css去试过嘛? 你去试试,一旦点击stop后不会有一点残留。难道这不是你要的结果么 *刚测试了下,不用非得opacity等于0,只要entry和leave不同即可(当然leave的opacity不能为1)。leave的opacity越小,表现越好。但是stop之后效果都能达到,无不可移除的阴影元素 |
追踪么,不要加太多语句;就这样,然后在稍微低一点的性能下测试就会很明显的发现问题。就像你说的手机性能会更严重一样(我在笔记本的节能模式下测试过,会很明显)
|
@EveLuty 十分神奇,进入和退出不同居然能解决我遇到的问题hhh |
别着急我这两天就看... |
好吧,这个问题其实我一直都知道,原因其实比较坑爹,和浏览器的 timer / 渲染机制有关系。举例来说:
这就是为什么 enter 和 leave 用不同的值可以解决这个问题。 至于能不能在 Vue 的机制里解决这个问题,还要再看看。 |
好吧hhh我仔细考虑过后觉得也是这个问题,还是谢谢各位帮忙了~ Evan You notifications@github.com于2016年3月25日周五 上午10:54写道:
|
抱歉再次开启此issue。。 |
@ClassicOldSong 应该是在不支持 rAF 的旧浏览器吧... 这个真没办法 |
@yyx990803 并不是。。。在最新的Chrome下也出现了 |
@ClassicOldSong 这... 那保险起见只能用 0.00001 大法了 |
Vue.js version
1.0.18
Reproduction Link
https://jsfiddle.net/ClassicOldSong/1utjmu60/5/
操作方法:点击Start filling,然后点击Start removing,观测结果即可
remove的时间间隔比fill要小,也就是说不应该出现多余残留的元素
而且这里的remove是直接清空数组,更不应该产生残留了
然而你仍然能看到元素慢慢地变多起来
console里有输出beforeLeave和afterLeave的触发次数,可以发现afterLeave的次数小于beforeLeave
Steps to reproduce
用v-for="data in data"创建一个列表模板,设置transition属性
至少创建退出动画,进入动画无关这个问题
(为了使效果更加明显建议退出后状态不要将高度设置为0或者将透明度设置为0)
创建$vm,绑定到刚刚创建的模板
情况1
连续快速地重复向$vm.data中添加然后删除对象的动作多次
情况2
向$vm.data中添加大量对象
然后清空$vm.data
然后立即向$vm.data中添加对象
连续快速地重复以上步骤多次
正常情况下情况2的效果比情况1明显一些
What is Expected?
元素被正常地移除并不再出现在Document内
What is actually happening?
部分元素残留在页面内没有被清除且仍然能够正常地响应事件
经过测试发现afterLeave事件被触发的次数有很大的几率比beforeLeave和leave事件的触发次数小,尤其在低性能设备上比如手机会更加严重
beforeLeave事件触发次数与leave事件触发次数始终保持一致,初步判断为leave事件的回调没有被正确地执行或者在执行前就被清理掉了
请尽快修复这个BUG!!谢谢!
The text was updated successfully, but these errors were encountered: