primefaces / primevue

Next Generation Vue UI Component Library
https://primevue.org
MIT License
10.61k stars 1.24k forks source link

Drawer : Template is always totaly build #6559

Closed ptorrent closed 1 week ago

ptorrent commented 1 month ago

Describe the bug

Hello,

Seems that Drawer is totaly rebuild every time I change the v-model:visible attribute. Is there a way to just build it the first time and show / hide it next time ?

Reproducer

https://stackblitz.com/edit/qkuurx?file=src%2FApp.vue

PrimeVue version

4.1.0

Vue version

4.x

Language

TypeScript

Build / Runtime

Vue CLI App

Browser(s)

All

Steps to reproduce the behavior

Just pu an alert inside the Drawer component, every time I change his visibility, the alert will fire.

Expected behavior

I think it will be good to build the content only once.. is there a way to do that ?

THanks for your support

CCodam commented 1 month ago

You could put the Drawer inside your component, instead of the other way around. https://stackblitz.com/edit/qkuurx-1oo7zd?file=src%2FApp.vue

ptorrent commented 1 month ago

Are you sure it helps? The idea is to create the drawer content only once at first visible =true. Now you recreate content everytime visibility go from false to true

ptorrent commented 1 month ago

From my point of view:

<Portal>
        <div v-if="containerVisible" :ref="maskRef" @mousedown="onMaskClick" :class="cx('mask')" :style="sx('mask', true, { position })" v-bind="ptm('mask')">
            <transition name="p-drawer" @enter="onEnter" @after-enter="onAfterEnter" @before-leave="onBeforeLeave" @leave="onLeave" @after-leave="onAfterLeave" appear v-bind="ptm('transition')">
                <div **v-if="visible"** :ref=

v-if="visible" is an error. Must be something like "visible || wasAlreadyOpened"... Everytime visible change from true to false, the content is removed... and everything is rebuild when visible = true again. Is there a workarround for this behavior ?

CCodam commented 1 month ago

Well technically it might be possible to use v-show instead of v-if, to keep the component in the real DOM and just toggle visibility instead of a full re-render. However there's a bunch of pitfalls with that approach, and while I can't talk for the Prime folk, I don't see them going down that road. The Dialog, Popover, Toast etc. all do the same, resides in the virtual DOM and gets rendered/destroyed when needed. You'll find the same behavior in other libraries too.

But I'll digress and let them respond.

While it's true that my first suggestion still renders and destroys the drawer on open/close, at least it only gets mounted once, hence the singular alert message.

If you're adamant on only rendering the Drawer once in the real DOM, it is possible to accomplish this by overriding some of the components functionality, and manipulating the real DOM element yourself. https://stackblitz.com/edit/qkuurx-c8k2pc?file=src%2FApp.vue

ptorrent commented 1 month ago

Thanks for your workarround, it works fine !

I think this feature is very useful. Sometime you need to build complext stuff inside a drawer (chart etc..) or just something that keep value until you decide to destroy it (not hidding it)

Thanks a lot

tugcekucukoglu commented 1 week ago

Thanks for the updates!