[Help] Filter Grid list
lannodev opened this issue · 3 comments
Hi, I'm trying to filter my grid list using an array object but the list doesn't update
const filteredSongs = computed(() => {
if (searchTerm.value == '') return library.songs;
return library.songs.filter((song) => {
return (
song.title.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) ||
song.name.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) ||
song.artist?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase())
);
});
});
async function pageProvider(pageNumber: number, pageSize: number) {
if (pageNumber == 0) pageNumber = 1;
let songs = filteredSongs.value.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
return songs;
}
Please could you give me an example like this ?
https://codesandbox.io/s/vue-virtual-scroll-grid-esm-vt27c?file=/App.vue
The component only refreshes itself when the input props change.
You may try converting your pageProvider
into a computed value, i.e. a function factory that computes a new pageProvider
when your search term changes.
Something like:
const computedPageProvider = computed(() => {
return async function pageProvider(pageNumber: number, pageSize: number) {
if (pageNumber == 0) pageNumber = 1;
let songs = filteredSongs.value.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
return songs;
}
})
Did not work :(
To resolve I had to add a key property:
<Grid
:length="filteredSongs.length"
:respectScrollToOnResize="true"
:pageSize="12"
:pageProviderDebounceTime="0"
:pageProvider="pageProvider"
:key="componentKey"
class="3xl: grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:md:grid-cols-4 xl:md:grid-cols-5 2xl:md:grid-cols-6">
<template v-slot:probe>
<MusicCard />
</template>
...
const filteredSongs = computed(() => {
componentKey.value += 1; //here
if (searchTerm.value == '') return library.songs;
The component only refreshes itself when the input props change.
You may try converting your
pageProvider
into a computed value, i.e. a function factory that computes a newpageProvider
when your search term changes.Something like:
const computedPageProvider = computed(() => { return async function pageProvider(pageNumber: number, pageSize: number) { if (pageNumber == 0) pageNumber = 1; let songs = filteredSongs.value.slice((pageNumber - 1) * pageSize, pageNumber * pageSize); return songs; } })
This doesn't work is because filteredSongs
is accessed only in the returned async function, so computed
doesn't count it as a dependency. Instead, it needs to be accessed in the function passed to computed
directly, like:
const computedPageProvider = computed(() => {
const filtered = filteredSongs.value
return async function pageProvider(pageNumber: number, pageSize: number) {
if (pageNumber == 0) pageNumber = 1;
let songs = filtered.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
return songs;
}
})
Compared to the solution of updating key
whenever filtered items change, this has the advantage that the entire grid does not get recreated so there is no noticeable screen flashing.