vuetifyjs / vuetify

🐉 Vue Component Framework
https://vuetifyjs.com
MIT License
39.6k stars 6.94k forks source link

[Feature Request] Virtual scrolling Treeview #9742

Open peteruithoven opened 4 years ago

peteruithoven commented 4 years ago

Problem to solve

The Treeview component doesn't seem flexible / extendable enough to combine it with a virtual scrolling solution, like: https://akryum.github.io/vue-virtual-scroller/

Proposed solution

Add (scoped) slots that would allow integrating a virtual scrolling solution.

Related: [Feature Request] Virtualization on Data table

HugoDelval commented 3 years ago

Would love to see that :+1: Would someone know a way to achieve this (maybe using directives?) as a temporary workaround?

giray123 commented 3 years ago

Waiting for this feature as well :partying_face:

JasonLandbridge commented 3 years ago

@HugoDelval, @giray123, @peteruithoven , I got stuck on this too and managed to solve it by doing the following:

See Demo

The example above is a v-treeview that looks and functions like a v-data-table.

Let's say I have items, which is an item[] with a 1000 entries. Each item (datarow) get's their own v-treeview wrapped in a v-lazy, I then loop over all the items and render them accordingly. Each v-treeview can expand and retract as much as it wants without breaking the lazy loading.

So far I have done this with 1000 items and it works perfectly!

giray123 commented 3 years ago

@JasonLandbridge great work! Actually, I would love to see a demo, if it would not take much time of yours. 👏

JasonLandbridge commented 3 years ago

@giray123, sure!

Demo

This is very bare-bones but it works!

giray123 commented 3 years ago

@JasonLandbridge it looks great! Thanks for the time to share it.

jennysol commented 3 years ago

Hello! I have a question regarding the v-treview It has a separate scrool for listing a matrix, and a card with specifications regarding the selected item, I would like to make it load the listing data according to the scrool, it is a lot of data and the request is very long. Without scrooling with root: null

bsataric commented 3 years ago

@HugoDelval, @giray123, @peteruithoven , I got stuck on this too and managed to solve it by doing the following:

See Demo

The example above is a v-treeview that looks and functions like a v-data-table.

Let's say I have items, which is an item[] with a 1000 entries. Each item (datarow) get's their own v-treeview wrapped in a v-lazy, I then loop over all the items and render them accordingly. Each v-treeview can expand and retract as much as it wants without breaking the lazy loading.

So far I have done this with 1000 items and it works perfectly!

Thanks for this example.

However I tried to change your code by adding 5000 children in the first node and all other nodes would have no children. Such data I have in my tree. When I do this RAM goes over 1GB. Can this be somehow fixed, or not? Having a lot of nodes on first level doesn't seem to create memory issues, but children do create problems. I think that's the whole point of virtuall scrolling to reduce rendering and memory consumption.

bsataric commented 2 years ago

@giray123, sure!

Demo

This is very bare-bones but it works!

Thanks again for this.

However how would this work with filtering prop (https://vuetifyjs.com/en/components/treeview/#search-and-filter)?

I tried every possible solution to make v-lazy dissapear if item is not filtered but if I try to change v-lazy min-height to zero by filter computed property (or if I bind value or v-model to filter computed property) v-lazy loses it's properties and becomes fixed as if there is no lazy loading at all hence the whole point is lost and memory increses again on large number of nodes. Filtering does work in that case and v-lazy dissapears it's just that it becomes fixed if nothing is entered in filter which is bad for RAM if there is thousands of nodes.

bsataric commented 2 years ago

OK I answered myself... It is necessary to create a custom function whose return value binds to :style of the enclosing v-lazy element This function calculates display none or '' depending weather treeview item passed to this function is filtered or not (we pass item object or parentitem). This function works basically the same way as treeview filter inside filtering example but it returns none or '' (for display property of the enclosing v-lazy). Changing min-height doens't work for some reason and fixates v-lazy which we don't want so I had to do it throught css display property instead.

nabenzine commented 1 year ago

@giray123, sure!

Demo

This is very bare-bones but it works!

I know that this is old, but it's really saving me much time, so thank you.

However I couldn't make it work with a v-model (for checkbox), the virtual scrolling break it I guess

JasonLandbridge commented 1 year ago

@nabenzine , It's a bit messy but here is a working example of where I've used it in my project with everything being selectable.

nabenzine commented 1 year ago

@nabenzine , It's a bit messy but here is a working example of where I've used it in my project with everything being selectable.

It work's great! thank you very much, you are a life saver !

JasonLandbridge commented 1 year ago

My pleasure, I'm impressed you figured it out from that mess :smile:

nabenzine commented 1 year ago

My pleasure, I'm impressed you figured it out from that mess 😄

One last question please, do you by any chance have ui freeze when you select all nodes ? I have a tree with 1000 node, and when I click select all, I take about 7 seconde to perform the selection, and it freezes the UI.

After a couple of hours of debugging, I found that the @input event is fired multiple time in a circular loop, as the :value changes, wich seems to cause the problem, a simple console.log() would probably show the case.

Any ideas would be greatly appreciated ! Thank you !

JasonLandbridge commented 1 year ago

I honestly have no idea and I would need to investigate it, it most likely is a bug in my own project as well

nabenzine commented 1 year ago

Reference in new iss

I have managed to fix the issue afterall, I just added a debounce for updateSelected method, it work's great !

image

I also replaced retrieveAllLeafs method with a recursive version, it doesn't add anything except less code to manage

image

Thank you again for saving me much time !

JasonLandbridge commented 1 year ago

Wow, thank you so much for posting this! This is something I will definitely use as well!