版本
2.5.11(以及更早的版本)
复现链接
https://jsfiddle.net/xb4172g8/
复现步骤
- 打开控制台并在输入字段中键入一些内容时观察
- 在名称字段中输入一些文本 -> Vue 重新渲染所有三个Textfield组件
- 在第21行将
{ ...this.$listeners }
替换为空对象 - 再次输入一些文本到任何字段 -> Vue 只重新渲染更新后的Textfield
预期结果是什么?
Vue 应该只重新渲染其属性已更改的组件。
实际发生的情况是什么?
在组件的渲染函数中使用 $listeners
导致组件在其父组件更新时始终被渲染,尽管其属性尚未更改。
5条答案
按热度按时间yxyvkwin1#
目前,我们在更新父级时总是设置
$listeners
,因此是的,如果在渲染函数中使用$listeners
,它会触发子项更新。也许可以通过确保在设置$listeners
之前更新监听器来防止这种情况(https://github.com/vuejs/vue/blob/dev/src/core/instance/lifecycle.js#L243)mzsu5hc02#
很遗憾,即使我们在设置
$listeners
之前进行了浅相等检查,您的具体示例仍然会重新渲染,因为您的@input
监听器在每次渲染时都作为一个新的匿名函数创建,所以从技术上讲它们是不同的。这类似于在每次渲染时将不同的匿名函数作为 prop 传递下去。neekobn83#
Has there been made any plans to implement such a check?
mkh04yzy4#
这个问题有什么解决办法吗?我不得不在透明 Package 器上手动设置所有监听器,但感觉不太对。实际上,Vue 3是如何工作的?
zf2sa74q5#
是否只有像vuetify这样的解决方案才能解决这个问题?