Skip to content
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

feat(VList): add lazy mode to VListGroup #16343

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open

Conversation

tinou98
Copy link

@tinou98 tinou98 commented Dec 29, 2022

Description

Add a lazy props to skip the rendering of children if the group has never been opened

Motivation and Context

This allows to render instantly a list with ~1k elements (see example in docs)

How Has This Been Tested?

Manually (patched in my project, used to crash Chrome and Firefox, now work instantly).
Also added 2 Cypress test.

Markup:

Available in the documentation

<template>
  <v-card>
    <v-card-title>List with {{ size }} elements</v-card-title>

    <v-card-text v-if="data">
      <v-list>
        <recursive-list :entry="data"></recursive-list>
      </v-list>
    </v-card-text>
    <v-card-actions v-else class="justify-center">
      <v-btn @click="data = MakeEntries()">Prepare</v-btn>
    </v-card-actions>
  </v-card>
</template>

<script lang="ts" setup>
  import { computed, h, ref, VNode } from 'vue'
  import { VListGroup, VListItem } from 'vuetify/components'
  export type Entry = {
    name: string,
    children?: Entry[],
  }
  /*
  <VListGroup v-if="entry.children" lazy>
    <template v-slot:activator="{ props }">
      <VListItem v-bind="props">
        {{ p.val.name }}
      </VListItem>
    </template>
    <RecursiveList :val="e" v-for="e in p.val.children" />
  </VListGroup>
  <VListItem v-else>
    {{ p.val.name }}
  </VListItem>
  */
  const RecursiveList = ({ entry }: { entry: Entry }): VNode =>
    entry.children
      ? h(VListGroup, { lazy: true }, {
        default: () => entry.children?.map(entry => RecursiveList({ entry })),
        activator: ({ props }: any) => h(VListItem, props, { default: () => entry.name }),
      })
      : h(VListItem, null, { default: () => entry.name })
  function MakeEntries (prefix = 'Prop', depth = 5): Entry {
    let children
    if (depth > 0) {
      children = []
      for (let i = 0; i < 5; ++i) {
        children.push(MakeEntries(prefix + '.' + i, depth - 1))
      }
    }
    return { name: prefix, children }
  }
  function GetSize (v: Entry): number {
    return v.children?.map(GetSize).reduce((acc, v) => acc + v, 1) ?? 1
  }
  const data = ref<Entry>()
  const size = computed(() => data.value ? GetSize(data.value) : 0)
</script>

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Improvement/refactoring (non-breaking change that doesn't add any features but makes things better)

Checklist:

  • The PR title is no longer than 64 characters.
  • The PR is submitted to the correct branch (master for bug fixes and documentation updates, dev for new features and backwards compatible changes and next for non-backwards compatible changes).
  • My code follows the code style of this project.
  • I've added relevant changes to the documentation (applies to new features and breaking changes in core library)

@nekosaur
Copy link
Member

There is a lazy composable that you might be able to use

@tinou98
Copy link
Author

tinou98 commented Jan 13, 2023

It does indeed simplify the code, but has the drawback of making lazy the default behaviour (might break/slow some application).
I've updated (but not the test/docs). If it's good, I'll update the rest.

@johnleider
Copy link
Member

Please update your fork and rebase this onto dev.

@johnleider johnleider added the S: has merge conflicts The pending Pull Request has merge conflicts label Jul 17, 2023
@johnleider johnleider marked this pull request as draft July 17, 2023 16:50
Add a `lazy` props to skip the rendering of children if the group has never
been opened

This allow to render instantly a list with ~1k elements (see example in docs)
@tinou98 tinou98 marked this pull request as ready for review August 11, 2023 16:37
@tinou98
Copy link
Author

tinou98 commented Aug 11, 2023

Rebased

@johnleider johnleider added T: feature A new feature and removed S: has merge conflicts The pending Pull Request has merge conflicts labels Aug 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: VList VList T: feature A new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants