Closed nekuz0r closed 1 year ago
I don't see this as a bug. Whenever the source <portal>
sends new vnodes, the content changes. Wether or not that new content actually looks like the old content which means nothing changed for the consumer is not taken into consideration.
Doing that would require to do a complete diff of he virtualDOM that the source <portal>
component(s) provided, which isn't really warranted considering performance implications.
What you are suggesting is a bit of a different feature. you want the event to only emit when the boolean value that it comes with actually flips. It wasn't intended to work that way before, but may be worth considering.
Changing this behaviour would constitute a breaking change though, strictly speaking
what about a new event targets-changed
(or some better name)?
I am not sure if this is related to this issue or if I should create my own, but the issue I am getting is whenever my v-model changes that is outside the portal the portal emits a change event. So on a text input this is happening on keyup so every keystroke is emitting the change event.
I am not sure why the portal would need to emit a change if it is not using any reactive objects. It seems to me that it should only emit the change if the reactive objects get modified.
Here is a simple child component example:
<template>
<section class="dashboard">
<portal to="toolbar">
<h1>Dashboard</h1>
</portal>
<input type="text" v-model="foo" />
</section>
</template>
The re-render of your components means that the portal receives updated slot content. The fact that this content is semantically the same doesn't matter - its new vnodes. That's how slots work, unrelated to portal-vue.
So the portal updates, which means the portal-target updates.
I think you should be able to prevent this from happening by using a scoped slot with the newer v-slot
syntax, since Vue will cache the scoped-slot function that's being generated:
<template>
<section class="dashboard">
<portal to="toolbar" v-slot:default>
<h1>Dashboard</h1>
</portal>
<input type="text" v-model="foo" />
</section>
</template>
The
change
event is triggered when aportal-target
is registered/unregistered.The
portal-target
component watches thetransports
object and anytime the content of it changes then thechange
event is triggered even though the content of theportal-target
did not changed.I expect it to be called only when the content is changed.
Changing the watch function @ https://github.com/LinusBorg/portal-vue/blob/develop/src/components/portal-target.tsx#L33 by the following seems to fix the issue: