3

I am using VueJS and Vuetify.

In v-data-table UI Component of vuetify, I want to save the current page that the current user is. For example, if the user is on the page 3 of 10, and he reloads the page, it will automatically go back to page 3 of 10. The current function is when the user reloads, it goes back to page 1 of 10.

footerOptions: {
    showFirstLastPage: true,
    showCurrentPage: true,
    itemsPerPageOptions: [20, 50, 100],
    itemsPerPageText: 'Data per Page',
},

getPagination(data) {
    sessionStorage.setItem('currentPage', data.page)
},
<v-data-table
    :headers="tableHeaders"
    :items="users"
    item-key="username"
    :loading="isLoading"
    @item-selected="itemSelect"
    @toggle-select-all="selectAll"
    @click:row="singleClick"
    @dblclick:row="doubleClick"
    @pagination="getPagination"
    :footer-props="footerOptions"
    show-select
    multi-sort
    dense>
</v-data-table>

Edit: I am already getting the current page and save it to session storage. Now, all I need to make that currentPage binded in the v-data-table. I tried to used the page prop of v-data-table but nothing happens. Still on page 1 even the currentPage is 2/3/4 and so on.

Kiko
  • 31
  • 6
  • You need to save the value between refreshes. web storage, cookies, query params, etc. see the answers on this post: [Persist variables between page loads](https://stackoverflow.com/questions/29986657/persist-variables-between-page-loads) for more details – yoduh Aug 30 '22 at 03:08
  • @yoduh, I think it's different. But I am able to store the current page number to the session storage. My problem now is how to apply the save paged to the v-data-table. I tried to used the page prop but nothing happens. – Kiko Aug 30 '22 at 03:14
  • I've posted an answer that should hopefully help you – yoduh Aug 30 '22 at 03:47

3 Answers3

2

Here is what you should try:

  1. add :page prop on v-data-table to bind the page number to a data property pageNum.

  2. listen for update:page event which fires from v-data-table any time the table's page value changes, then call a method named pageChange

  3. in the pageChange method you should save the page value (passed in for you by the event) to localStorage: localStorage.setItem("page", newPage);

  4. on component creation, set pageNum to the value saved in localStorage: this.pageNum = localStorage.getItem("page");

simplified component code shown below:

<template>
  <div>
    <v-data-table
      :headers="tableHeaders"
      :items="users"
      :page="pageNum"
      @update:page="pageChange"
    >
    </v-data-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      pageNum: 1,
      tableHeaders: [],
      users: [],
    };
  },
  methods: {
    pageChange(newPage) {
      localStorage.setItem("page", newPage);
    },
  },
  created() {
    this.pageNum = localStorage.getItem("page");
  },
};
</script>

This will persist the page number value that v-data-table holds across page refreshes. You might want to think about clearing localStorage, localStorage.clear();, when the user navigates to a different page so if they come back to the page with v-data-table they are on page 1 again.

yoduh
  • 7,074
  • 2
  • 11
  • 21
  • Thanks for this! We successfully used it. We also improved on it by saving & loading the whole `options` object because then other options like items per page, sorting, and filtering will also be persisted. We only reset the options when the underlying data count changes. Mind: If only `page` is persisted, the visible data might be vastly different because of sorting or especially items per page (as page 5 on 10 per page starts at #41, while page 5 on 5 per page starts at #21) – Chonez Sep 29 '22 at 14:34
0

I think the issue may be that your users is requested from backend? You should change the value of pageNum binded to v-data-table after users are got from remote.

<template>
  <v-data-table
    :items="users"
    :page="pageNum"
  >
  </v-data-table>
</template>

<script>
export default {
  data() {
    return {
      pageNum: 1,
      users: [],
    };
  },
  created() {
    getUsers().then((promise)=>{
      this.users = promise.data
      this.pageNum = sessionStorage.getItem('currentPage');
    })
  },
};
</script>

The key point is that you should set the value of pageNum when v-data-table already has multiple pages.

Yue JIN
  • 1,047
  • 1
  • 10
  • 20
0

Here's a super simple solution using the power of setup function and VueUse!

Check this codesandbox I made: https://codesandbox.io/s/stack-73536361-pagination-currentpage-vueuse-3yycx0?file=/src/components/Example.vue

VueUse is a collection of utility functions based on Composition API. With support for Vue 2 & 3. In this example I'll use the useStorage function that simplifies the process to create a reactive LocalStorage/SessionStorage.

  1. First, install the VueUse npm package: npm i @vueuse/core

  2. Then in your vue component import useStorage from @vueuse/core. And configure your reactive variable in the setup function like this:

<script>
import { useStorage } from '@vueuse/core'
export default {
   name: 'Example',
   setup() {
      const state = useStorage('my-page', {
         page: 1
      })
      return { state }
   },
   data: () => ({
      ...
   })
}
</script>
  1. Then in your v-data-table get/set the current page with the page prop and make sure to use the .sync modifier and link it to your reactive variable. In this example state.page.
<v-data-table
    :headers="headers"
    :items="desserts"
    :page.sync="state.page"
    :footer-props="{
    showFirstLastPage: true,
    showCurrentPage: true,
    :items-per-page="3"
    itemsPerPageOptions: [3, 50, 10],
    itemsPerPageText: 'Data per Page',
    }"
    class="elevation-1"
></v-data-table>
  1. That's it! VueUse is awesome, you can add more variables to your reactive state to save the items per page or anything you want.

enter image description here

cmfc31
  • 1,385
  • 2
  • 8
  • 9