Vuetify pagination not updating reactive variable

200 Views Asked by At

I'm following this simple example of vuetify external pagination https://vuetifyjs.com/en/components/data-tables/pagination/#external-pagination . Difference is that my code gets the data from an asynchronous request. Surprisingly it doesn't work.

Possible that I'm doing something wrong, but reactivity examples with composition api are not a lot out there. Template:

 <template>
   <v-container class="w-100">
     <v-card>
       <v-card-title align="left" class="mb-5 mt-3">Users</v-card-title>
       <v-data-table
        :headers="headers"
        :items="users"
        :items-per-page="pageSize"
        hide-default-footer
        class="elevation-1"
       >
       <template v-slot:bottom>
         <div class="text-center pt-2">
           <v-pagination
             v-model="page"
            :length="pageNumbers"
           ></v-pagination>
        </div>
      </template>
    </v-data-table>
  </v-card>
 </v-container>
</template>

Script short version:

const users = ref([])
const pageSize = ref(10)
const page = ref(1)
const totalUserCount = ref(1)
const pageNumbers = computed(() => Math.ceil(totalUserCount.value / pageSize.value))

const loadUsers = async (page) => {
  await HTTPClient.getData('/user-manager/users?page=' + page).then(response => {
    users.value = response.data.result
    pageSize.value = response.data.page_size
    totalUserCount.value = response.data.count
});

}

await loadUsers(page.value)

Now when clicking on the pagination button, my guess is that it should update the page reactive variable, which then should re-render the component (including the loadUser function call). But nothing happens. I'm quite new with vue, so maybe I shouldn't think in React way. Tried to find a solution on the vue js official documentation page, but the examples given are too basic to get any direction from it. Thanks.

1

There are 1 best solutions below

1
On BEST ANSWER

When a component rerenders, it only reruns code that is executed in the <template> of the component. Script code and the functions within it don't automatically rerun. There are two ways to have your loadUsers function rerun when page updates.

1. Using update:model-value event

This is the event that v-model uses to update it's binded variable. You can use this same event to run some code whenever the v-model updates.

<v-pagination
  v-model="page"
  @update:model-value="loadUsers"
  :length="pageNumbers"
></v-pagination>

2. Using a watcher

watchers are used to run code in response to some change in state. You can use this to "watch" the page value, and run some code any time it updates.

watch(page, () => {
  loadUsers()
})

One other thing is that I would remove the page parameter from the loadUsers definition as it's unnecessary. You can just reference the ref itself with page.value.

const loadUsers = async () => {
  await HTTPClient.getData('/user-manager/users?page=' + page.value)
  ...
}

Vue Playground example