feat: add virtual scroll to links dropdown

Enhances dropdown performance by implementing virtual scrolling with VList from virtua/vue library. This optimization improves rendering efficiency for large link lists by only rendering visible items.
This commit is contained in:
ccbikai 2025-03-02 14:33:47 +08:00
parent dd7b898a11
commit 6070f2f5c3

View file

@ -1,7 +1,8 @@
<script setup> <script setup>
import { useUrlSearchParams } from '@vueuse/core' import { useUrlSearchParams, watchDebounced } from '@vueuse/core'
import { safeDestr } from 'destr' import { safeDestr } from 'destr'
import { Check, ChevronsUpDown } from 'lucide-vue-next' import { Check, ChevronsUpDown } from 'lucide-vue-next'
import { VList } from 'virtua/vue'
const emit = defineEmits(['change']) const emit = defineEmits(['change'])
@ -17,9 +18,9 @@ onMounted(() => {
getLinks() getLinks()
}) })
watch(selectedLinks, (value) => { watchDebounced(selectedLinks, (value) => {
emit('change', 'slug', value.join(',')) emit('change', 'slug', value.join(','))
}) }, { debounce: 500, maxWait: 1000 })
function restoreFilters() { function restoreFilters() {
const searchParams = useUrlSearchParams('history') const searchParams = useUrlSearchParams('history')
@ -57,20 +58,23 @@ onBeforeMount(() => {
<CommandEmpty>No link found.</CommandEmpty> <CommandEmpty>No link found.</CommandEmpty>
<CommandList> <CommandList>
<CommandGroup> <CommandGroup>
<CommandItem <VList
v-for="link in links" v-slot="{ item: link }"
:key="link.slug" :data="links"
:value="link.slug" :style="{ height: '292px' }"
@select="isOpen = false"
> >
<Check <CommandItem
:class="cn( :value="link.slug"
'mr-2 h-4 w-4', >
selectedLinks.includes(link.slug) ? 'opacity-100' : 'opacity-0', <Check
)" :class="cn(
/> 'mr-2 h-4 w-4',
{{ link.slug }} selectedLinks.includes(link.slug) ? 'opacity-100' : 'opacity-0',
</CommandItem> )"
/>
{{ link.slug }}
</CommandItem>
</VList>
</CommandGroup> </CommandGroup>
</CommandList> </CommandList>
</Command> </Command>